@didcid/cipher 0.1.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/aes-B3jnKULi.cjs +1652 -0
- package/dist/cjs/{cipher-base-D2GtcXrx.cjs → cipher-base-CsSWgNEp.cjs} +235 -619
- package/dist/cjs/cipher-node.cjs +2 -1
- package/dist/cjs/cipher-web.cjs +2 -1
- package/dist/cjs/passphrase.cjs +118 -0
- package/dist/esm/cipher-base.js +23 -15
- package/dist/esm/cipher-base.js.map +1 -1
- package/dist/esm/concat-kdf.js +52 -0
- package/dist/esm/concat-kdf.js.map +1 -0
- package/dist/esm/jwe.js +124 -0
- package/dist/esm/jwe.js.map +1 -0
- package/dist/esm/passphrase.js +44 -0
- package/dist/esm/passphrase.js.map +1 -0
- package/dist/types/cipher-base.d.ts +6 -4
- package/dist/types/concat-kdf.d.ts +13 -0
- package/dist/types/jwe.d.ts +24 -0
- package/dist/types/passphrase.d.ts +10 -0
- package/dist/types/types.d.ts +6 -4
- package/package.json +10 -2
package/dist/cjs/cipher-node.cjs
CHANGED
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var bip39 = require('bip39');
|
|
6
|
-
var cipherBase = require('./cipher-base-
|
|
6
|
+
var cipherBase = require('./cipher-base-CsSWgNEp.cjs');
|
|
7
7
|
var crypto = require('crypto');
|
|
8
8
|
var HDKeyNode = require('hdkey');
|
|
9
9
|
require('@noble/secp256k1');
|
|
10
|
+
require('./aes-B3jnKULi.cjs');
|
|
10
11
|
require('canonicalize');
|
|
11
12
|
|
|
12
13
|
function _interopNamespaceDefault(e) {
|
package/dist/cjs/cipher-web.cjs
CHANGED
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var bip39 = require('bip39');
|
|
6
|
-
var cipherBase = require('./cipher-base-
|
|
6
|
+
var cipherBase = require('./cipher-base-CsSWgNEp.cjs');
|
|
7
7
|
var HDKeyBrowser = require('@didcid/browser-hdkey');
|
|
8
8
|
require('@noble/secp256k1');
|
|
9
|
+
require('./aes-B3jnKULi.cjs');
|
|
9
10
|
require('canonicalize');
|
|
10
11
|
|
|
11
12
|
function _interopNamespaceDefault(e) {
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var aes = require('./aes-B3jnKULi.cjs');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* PBKDF (RFC 2898). Can be used to create a key from password and salt.
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
// Common prologue and epilogue for sync/async functions
|
|
10
|
+
function pbkdf2Init(hash, _password, _salt, _opts) {
|
|
11
|
+
aes.ahash(hash);
|
|
12
|
+
const opts = aes.checkOpts$1({ dkLen: 32, asyncTick: 10 }, _opts);
|
|
13
|
+
const { c, dkLen, asyncTick } = opts;
|
|
14
|
+
aes.anumber(c);
|
|
15
|
+
aes.anumber(dkLen);
|
|
16
|
+
aes.anumber(asyncTick);
|
|
17
|
+
if (c < 1)
|
|
18
|
+
throw new Error('iterations (c) should be >= 1');
|
|
19
|
+
const password = aes.kdfInputToBytes(_password);
|
|
20
|
+
const salt = aes.kdfInputToBytes(_salt);
|
|
21
|
+
// DK = PBKDF2(PRF, Password, Salt, c, dkLen);
|
|
22
|
+
const DK = new Uint8Array(dkLen);
|
|
23
|
+
// U1 = PRF(Password, Salt + INT_32_BE(i))
|
|
24
|
+
const PRF = aes.hmac.create(hash, password);
|
|
25
|
+
const PRFSalt = PRF._cloneInto().update(salt);
|
|
26
|
+
return { c, dkLen, asyncTick, DK, PRF, PRFSalt };
|
|
27
|
+
}
|
|
28
|
+
function pbkdf2Output(PRF, PRFSalt, DK, prfW, u) {
|
|
29
|
+
PRF.destroy();
|
|
30
|
+
PRFSalt.destroy();
|
|
31
|
+
if (prfW)
|
|
32
|
+
prfW.destroy();
|
|
33
|
+
aes.clean(u);
|
|
34
|
+
return DK;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* PBKDF2-HMAC: RFC 2898 key derivation function. Async version.
|
|
38
|
+
* @example
|
|
39
|
+
* await pbkdf2Async(sha256, 'password', 'salt', { dkLen: 32, c: 500_000 });
|
|
40
|
+
*/
|
|
41
|
+
async function pbkdf2Async(hash, password, salt, opts) {
|
|
42
|
+
const { c, dkLen, asyncTick, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts);
|
|
43
|
+
let prfW; // Working copy
|
|
44
|
+
const arr = new Uint8Array(4);
|
|
45
|
+
const view = aes.createView$1(arr);
|
|
46
|
+
const u = new Uint8Array(PRF.outputLen);
|
|
47
|
+
// DK = T1 + T2 + ⋯ + Tdklen/hlen
|
|
48
|
+
for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) {
|
|
49
|
+
// Ti = F(Password, Salt, c, i)
|
|
50
|
+
const Ti = DK.subarray(pos, pos + PRF.outputLen);
|
|
51
|
+
view.setInt32(0, ti, false);
|
|
52
|
+
// F(Password, Salt, c, i) = U1 ^ U2 ^ ⋯ ^ Uc
|
|
53
|
+
// U1 = PRF(Password, Salt + INT_32_BE(i))
|
|
54
|
+
(prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u);
|
|
55
|
+
Ti.set(u.subarray(0, Ti.length));
|
|
56
|
+
await aes.asyncLoop(c - 1, asyncTick, () => {
|
|
57
|
+
// Uc = PRF(Password, Uc−1)
|
|
58
|
+
PRF._cloneInto(prfW).update(u).digestInto(u);
|
|
59
|
+
for (let i = 0; i < Ti.length; i++)
|
|
60
|
+
Ti[i] ^= u[i];
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return pbkdf2Output(PRF, PRFSalt, DK, prfW, u);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* SHA2-512 a.k.a. sha512 and sha384. It is slower than sha256 in js because u64 operations are slow.
|
|
68
|
+
*
|
|
69
|
+
* Check out [RFC 4634](https://datatracker.ietf.org/doc/html/rfc4634) and
|
|
70
|
+
* [the paper on truncated SHA512/256](https://eprint.iacr.org/2010/548.pdf).
|
|
71
|
+
* @module
|
|
72
|
+
* @deprecated
|
|
73
|
+
*/
|
|
74
|
+
/** @deprecated Use import from `noble/hashes/sha2` module */
|
|
75
|
+
const sha512 = aes.sha512;
|
|
76
|
+
|
|
77
|
+
const ENC_ITER_DEFAULT = 100_000;
|
|
78
|
+
const IV_LEN = 12;
|
|
79
|
+
const SALT_LEN = 16;
|
|
80
|
+
function getIterations() {
|
|
81
|
+
if (typeof process !== 'undefined' && process.env?.PBKDF2_ITERATIONS) {
|
|
82
|
+
const parsed = parseInt(process.env.PBKDF2_ITERATIONS, 10);
|
|
83
|
+
if (!isNaN(parsed) && parsed > 0) {
|
|
84
|
+
return parsed;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return ENC_ITER_DEFAULT;
|
|
88
|
+
}
|
|
89
|
+
async function encryptWithPassphrase(plaintext, pass) {
|
|
90
|
+
const salt = aes.randomBytes(SALT_LEN);
|
|
91
|
+
const iv = aes.randomBytes(IV_LEN);
|
|
92
|
+
const key = await deriveKey(pass, salt);
|
|
93
|
+
const cipher = aes.gcm(key, iv);
|
|
94
|
+
const ct = cipher.encrypt(new TextEncoder().encode(plaintext));
|
|
95
|
+
return { salt: b64(salt), iv: b64(iv), data: b64(ct) };
|
|
96
|
+
}
|
|
97
|
+
async function decryptWithPassphrase(blob, pass) {
|
|
98
|
+
const salt = ub64(blob.salt);
|
|
99
|
+
const iv = ub64(blob.iv);
|
|
100
|
+
const data = ub64(blob.data);
|
|
101
|
+
const key = await deriveKey(pass, salt);
|
|
102
|
+
const cipher = aes.gcm(key, iv);
|
|
103
|
+
const pt = cipher.decrypt(data);
|
|
104
|
+
return new TextDecoder().decode(pt);
|
|
105
|
+
}
|
|
106
|
+
const b64 = (buf) => {
|
|
107
|
+
return Buffer.from(buf).toString('base64');
|
|
108
|
+
};
|
|
109
|
+
const ub64 = (b64) => {
|
|
110
|
+
return new Uint8Array(Buffer.from(b64, 'base64'));
|
|
111
|
+
};
|
|
112
|
+
async function deriveKey(pass, salt) {
|
|
113
|
+
const enc = new TextEncoder();
|
|
114
|
+
return pbkdf2Async(sha512, enc.encode(pass), salt, { c: getIterations(), dkLen: 32 });
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
exports.decryptWithPassphrase = decryptWithPassphrase;
|
|
118
|
+
exports.encryptWithPassphrase = encryptWithPassphrase;
|
package/dist/esm/cipher-base.js
CHANGED
|
@@ -6,6 +6,7 @@ import { xchacha20poly1305 } from '@noble/ciphers/chacha';
|
|
|
6
6
|
import { managedNonce } from '@noble/ciphers/webcrypto/utils';
|
|
7
7
|
import { bytesToUtf8, utf8ToBytes } from '@noble/ciphers/utils';
|
|
8
8
|
import { base64url } from 'multiformats/bases/base64';
|
|
9
|
+
import { buildJweCompact, parseJweCompact, isJweCompact } from './jwe.js';
|
|
9
10
|
import canonicalizeModule from 'canonicalize';
|
|
10
11
|
const canonicalize = canonicalizeModule;
|
|
11
12
|
// Polyfill for synchronous signatures
|
|
@@ -61,16 +62,27 @@ export default class CipherBase {
|
|
|
61
62
|
const signature = secp.Signature.fromCompact(sigHex);
|
|
62
63
|
return secp.verify(signature, msgHash, compressedPublicKeyBytes);
|
|
63
64
|
}
|
|
64
|
-
encryptBytes(
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
65
|
+
encryptBytes(recipientPubKey, data) {
|
|
66
|
+
return buildJweCompact(recipientPubKey, data);
|
|
67
|
+
}
|
|
68
|
+
decryptBytes(recipientPrivKey, ciphertext, legacyPubKey) {
|
|
69
|
+
if (isJweCompact(ciphertext)) {
|
|
70
|
+
return parseJweCompact(recipientPrivKey, ciphertext);
|
|
71
|
+
}
|
|
72
|
+
if (legacyPubKey) {
|
|
73
|
+
return this.decryptBytesLegacy(legacyPubKey, recipientPrivKey, ciphertext);
|
|
74
|
+
}
|
|
75
|
+
throw new Error('Cannot decrypt: not a JWE and no legacy public key provided. Pass legacyPubKey as the third argument for old ciphertext.');
|
|
76
|
+
}
|
|
77
|
+
encryptMessage(recipientPubKey, message) {
|
|
78
|
+
const data = utf8ToBytes(message);
|
|
79
|
+
return this.encryptBytes(recipientPubKey, data);
|
|
72
80
|
}
|
|
73
|
-
|
|
81
|
+
decryptMessage(recipientPrivKey, ciphertext, legacyPubKey) {
|
|
82
|
+
const data = this.decryptBytes(recipientPrivKey, ciphertext, legacyPubKey);
|
|
83
|
+
return bytesToUtf8(data);
|
|
84
|
+
}
|
|
85
|
+
decryptBytesLegacy(pubKey, privKey, ciphertext) {
|
|
74
86
|
const priv = base64url.baseDecode(privKey.d);
|
|
75
87
|
const pub = this.convertJwkToCompressedBytes(pubKey);
|
|
76
88
|
const ss = secp.getSharedSecret(priv, pub);
|
|
@@ -79,12 +91,8 @@ export default class CipherBase {
|
|
|
79
91
|
const cipherdata = base64url.baseDecode(ciphertext);
|
|
80
92
|
return chacha.decrypt(cipherdata);
|
|
81
93
|
}
|
|
82
|
-
|
|
83
|
-
const data =
|
|
84
|
-
return this.encryptBytes(pubKey, privKey, data);
|
|
85
|
-
}
|
|
86
|
-
decryptMessage(pubKey, privKey, ciphertext) {
|
|
87
|
-
const data = this.decryptBytes(pubKey, privKey, ciphertext);
|
|
94
|
+
decryptMessageLegacy(pubKey, privKey, ciphertext) {
|
|
95
|
+
const data = this.decryptBytesLegacy(pubKey, privKey, ciphertext);
|
|
88
96
|
return bytesToUtf8(data);
|
|
89
97
|
}
|
|
90
98
|
hasLeadingZeroBits(hexHash, bits) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cipher-base.js","sourceRoot":"","sources":["../../src/cipher-base.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"cipher-base.js","sourceRoot":"","sources":["../../src/cipher-base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,IAAI,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAC7D,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAEtD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC1E,OAAO,kBAAkB,MAAM,cAAc,CAAC;AAC9C,MAAM,YAAY,GAAG,kBAA2D,CAAC;AAEjF,sCAAsC;AACtC,IAAI,CAAC,GAAG,CAAC,cAAc,GAAG,CAAC,CAAa,EAAE,GAAG,CAAe,EAAc,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAEzH,MAAM,CAAC,OAAO,OAAgB,UAAU;IAKpC,gBAAgB;QACZ,OAAO,KAAK,CAAC,gBAAgB,EAAE,CAAC;IACpC,CAAC;IAED,WAAW,CAAC,eAA2B;QACnC,MAAM,wBAAwB,GAAG,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;QACpE,MAAM,sBAAsB,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,wBAAwB,CAAC,CAAC;QAC7E,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;QACzE,MAAM,0BAA0B,GAAG,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACjE,MAAM,CAAC,GAAG,SAAS,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;QAChD,MAAM,CAAC,GAAG,SAAS,CAAC,UAAU,CAAC,0BAA0B,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAC3E,MAAM,CAAC,GAAG,SAAS,CAAC,UAAU,CAAC,0BAA0B,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAE5E,MAAM,SAAS,GAAmB;YAC9B,GAAG,EAAE,IAAI;YACT,GAAG,EAAE,WAAW;YAChB,CAAC;YACD,CAAC;SACJ,CAAC;QAEF,MAAM,UAAU,GAAoB,EAAE,GAAG,SAAS,EAAE,CAAC,EAAE,CAAC;QAExD,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;IACrC,CAAC;IAED,iBAAiB;QACb,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE,CAAC;QAC9C,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IAED,2BAA2B,CAAC,GAAmB;QAC3C,MAAM,MAAM,GAAG,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAG,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;QACjE,OAAO,IAAI,UAAU,CAAC,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC;IAC/C,CAAC;IAED,WAAW,CAAC,GAAwB;QAChC,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QACzB,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC7C,CAAC;IAED,gBAAgB,CAAC,IAAa;QAC1B,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED,QAAQ,CAAC,IAAa;QAClB,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC;IACzD,CAAC;IAED,QAAQ,CAAC,OAAe,EAAE,UAA2B;QACjD,MAAM,OAAO,GAAG,SAAS,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QACnD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC9C,OAAO,SAAS,CAAC,YAAY,EAAE,CAAC;IACpC,CAAC;IAED,SAAS,CAAC,OAAe,EAAE,MAAc,EAAE,SAAyB;QAChE,MAAM,wBAAwB,GAAG,IAAI,CAAC,2BAA2B,CAAC,SAAS,CAAC,CAAC;QAC7E,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACrD,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,wBAAwB,CAAC,CAAC;IACrE,CAAC;IAED,YAAY,CAAC,eAA+B,EAAE,IAAgB;QAC1D,OAAO,eAAe,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;IAClD,CAAC;IAED,YAAY,CAAC,gBAAiC,EAAE,UAAkB,EAAE,YAA6B;QAC7F,IAAI,YAAY,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3B,OAAO,eAAe,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC;QACzD,CAAC;QACD,IAAI,YAAY,EAAE,CAAC;YACf,OAAO,IAAI,CAAC,kBAAkB,CAAC,YAAY,EAAE,gBAAgB,EAAE,UAAU,CAAC,CAAC;QAC/E,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,0HAA0H,CAAC,CAAC;IAChJ,CAAC;IAED,cAAc,CAAC,eAA+B,EAAE,OAAe;QAC3D,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QAClC,OAAO,IAAI,CAAC,YAAY,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;IACpD,CAAC;IAED,cAAc,CAAC,gBAAiC,EAAE,UAAkB,EAAE,YAA6B;QAC/F,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,gBAAgB,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;QAC3E,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAED,kBAAkB,CAAC,MAAsB,EAAE,OAAwB,EAAE,UAAkB;QACnF,MAAM,IAAI,GAAG,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,2BAA2B,CAAC,MAAM,CAAC,CAAC;QACrD,MAAM,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC3C,MAAM,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC5B,MAAM,MAAM,GAAG,YAAY,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,CAAC;QACpD,MAAM,UAAU,GAAG,SAAS,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QACpD,OAAO,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACtC,CAAC;IAED,oBAAoB,CAAC,MAAsB,EAAE,OAAwB,EAAE,UAAkB;QACrF,MAAM,IAAI,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;QAClE,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAED,kBAAkB,CAAC,OAAe,EAAE,IAAY;QAC5C,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;QACpF,OAAO,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IAC/C,CAAC;IAED,cAAc,CAAC,GAAW,EAAE,UAAkB;QAC1C,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC,IAAI,UAAU,GAAG,GAAG,EAAE,CAAC;YACtE,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;QACjF,CAAC;QAED,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,OAAO,IAAI,EAAE,CAAC;YACV,MAAM,SAAS,GAAG;gBACd,GAAG,GAAG;gBACN,GAAG,EAAE;oBACD,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;oBACzB,UAAU;iBACb;aACJ,CAAC;YACF,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YAEtC,IAAI,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,CAAC;gBAC5C,OAAO,SAAS,CAAC;YACrB,CAAC;YAED,KAAK,EAAE,CAAC;QACZ,CAAC;IACL,CAAC;IAED,gBAAgB,CAAC,GAAW;QACxB,IACI,CAAC,GAAG;YACJ,OAAO,GAAG,KAAK,QAAQ;YACvB,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC;YACf,OAAQ,GAAW,CAAC,GAAG,KAAK,QAAQ;YACpC,OAAQ,GAAW,CAAC,GAAG,CAAC,KAAK,KAAK,QAAQ;YAC1C,OAAQ,GAAW,CAAC,GAAG,CAAC,UAAU,KAAK,QAAQ,EACjD,CAAC;YACC,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAEhC,OAAO,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAG,GAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACtE,CAAC;CACJ"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { sha256 } from '@noble/hashes/sha256';
|
|
2
|
+
/**
|
|
3
|
+
* Concat KDF (Single Step KDF) per NIST SP 800-56A and RFC 7518 §4.6.2.
|
|
4
|
+
*
|
|
5
|
+
* Derives a symmetric key from an ECDH shared secret for use in JWE.
|
|
6
|
+
*
|
|
7
|
+
* @param sharedSecret - The raw ECDH shared secret (Z)
|
|
8
|
+
* @param keyBitLength - Desired key length in bits (e.g. 128, 256)
|
|
9
|
+
* @param algorithmId - The "enc" value for ECDH-ES or "alg" for ECDH-ES+A*KW
|
|
10
|
+
* @param apu - Agreement PartyUInfo (typically empty)
|
|
11
|
+
* @param apv - Agreement PartyVInfo (typically empty)
|
|
12
|
+
* @returns Derived key as Uint8Array
|
|
13
|
+
*/
|
|
14
|
+
export function concatKdf(sharedSecret, keyBitLength, algorithmId, apu = new Uint8Array(0), apv = new Uint8Array(0)) {
|
|
15
|
+
const algIdBytes = new TextEncoder().encode(algorithmId);
|
|
16
|
+
// Build otherInfo per RFC 7518 §4.6.2:
|
|
17
|
+
// AlgorithmID = len(algId) || algId
|
|
18
|
+
// PartyUInfo = len(apu) || apu
|
|
19
|
+
// PartyVInfo = len(apv) || apv
|
|
20
|
+
// SuppPubInfo = keydatalen (32-bit BE, in bits)
|
|
21
|
+
const otherInfo = concatBytes(uint32BE(algIdBytes.length), algIdBytes, uint32BE(apu.length), apu, uint32BE(apv.length), apv, uint32BE(keyBitLength));
|
|
22
|
+
const hashLength = 256; // SHA-256 output in bits
|
|
23
|
+
const reps = Math.ceil(keyBitLength / hashLength);
|
|
24
|
+
const result = new Uint8Array(reps * 32);
|
|
25
|
+
for (let counter = 1; counter <= reps; counter++) {
|
|
26
|
+
const input = concatBytes(uint32BE(counter), sharedSecret, otherInfo);
|
|
27
|
+
const digest = sha256(input);
|
|
28
|
+
result.set(digest, (counter - 1) * 32);
|
|
29
|
+
}
|
|
30
|
+
return result.slice(0, keyBitLength / 8);
|
|
31
|
+
}
|
|
32
|
+
function uint32BE(value) {
|
|
33
|
+
const buf = new Uint8Array(4);
|
|
34
|
+
buf[0] = (value >>> 24) & 0xff;
|
|
35
|
+
buf[1] = (value >>> 16) & 0xff;
|
|
36
|
+
buf[2] = (value >>> 8) & 0xff;
|
|
37
|
+
buf[3] = value & 0xff;
|
|
38
|
+
return buf;
|
|
39
|
+
}
|
|
40
|
+
function concatBytes(...arrays) {
|
|
41
|
+
let totalLength = 0;
|
|
42
|
+
for (const arr of arrays)
|
|
43
|
+
totalLength += arr.length;
|
|
44
|
+
const result = new Uint8Array(totalLength);
|
|
45
|
+
let offset = 0;
|
|
46
|
+
for (const arr of arrays) {
|
|
47
|
+
result.set(arr, offset);
|
|
48
|
+
offset += arr.length;
|
|
49
|
+
}
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=concat-kdf.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"concat-kdf.js","sourceRoot":"","sources":["../../src/concat-kdf.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE9C;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,SAAS,CACrB,YAAwB,EACxB,YAAoB,EACpB,WAAmB,EACnB,MAAkB,IAAI,UAAU,CAAC,CAAC,CAAC,EACnC,MAAkB,IAAI,UAAU,CAAC,CAAC,CAAC;IAEnC,MAAM,UAAU,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAEzD,uCAAuC;IACvC,uCAAuC;IACvC,qCAAqC;IACrC,qCAAqC;IACrC,mDAAmD;IACnD,MAAM,SAAS,GAAG,WAAW,CACzB,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,UAAU,EACvC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,EACzB,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,EACzB,QAAQ,CAAC,YAAY,CAAC,CACzB,CAAC;IAEF,MAAM,UAAU,GAAG,GAAG,CAAC,CAAC,yBAAyB;IACjD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC,CAAC;IAClD,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;IAEzC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC;QAC/C,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;QACtE,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC7B,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,OAAO,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,GAAG,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,QAAQ,CAAC,KAAa;IAC3B,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;IAC9B,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IAC/B,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IAC/B,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC;IAC9B,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC;IACtB,OAAO,GAAG,CAAC;AACf,CAAC;AAED,SAAS,WAAW,CAAC,GAAG,MAAoB;IACxC,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,KAAK,MAAM,GAAG,IAAI,MAAM;QAAE,WAAW,IAAI,GAAG,CAAC,MAAM,CAAC;IACpD,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,CAAC;IAC3C,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QACvB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACxB,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC;IACzB,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC"}
|
package/dist/esm/jwe.js
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import * as secp from '@noble/secp256k1';
|
|
2
|
+
import { gcm } from '@noble/ciphers/aes';
|
|
3
|
+
import { base64url } from 'multiformats/bases/base64';
|
|
4
|
+
import { concatKdf } from './concat-kdf.js';
|
|
5
|
+
const ENCODER = new TextEncoder();
|
|
6
|
+
const DECODER = new TextDecoder();
|
|
7
|
+
/**
|
|
8
|
+
* Build a JWE Compact Serialization string using ECDH-ES + A256GCM.
|
|
9
|
+
*
|
|
10
|
+
* Uses an ephemeral secp256k1 keypair for key agreement.
|
|
11
|
+
* The sender's identity key is NOT involved — only the recipient's public key.
|
|
12
|
+
*
|
|
13
|
+
* @param recipientPubKey - Recipient's public key (secp256k1 JWK)
|
|
14
|
+
* @param plaintext - Data to encrypt
|
|
15
|
+
* @returns JWE Compact string: header.encryptedKey.iv.ciphertext.tag
|
|
16
|
+
*/
|
|
17
|
+
export function buildJweCompact(recipientPubKey, plaintext) {
|
|
18
|
+
// 1. Generate ephemeral keypair
|
|
19
|
+
const ephemeralPrivKey = secp.utils.randomPrivateKey();
|
|
20
|
+
const ephemeralPubKeyBytes = secp.getPublicKey(ephemeralPrivKey);
|
|
21
|
+
// Get uncompressed public key coordinates for the JWE header
|
|
22
|
+
const ephemeralPubHex = secp.etc.bytesToHex(ephemeralPubKeyBytes);
|
|
23
|
+
const curvePoints = secp.ProjectivePoint.fromHex(ephemeralPubHex);
|
|
24
|
+
const uncompressed = curvePoints.toRawBytes(false);
|
|
25
|
+
const epkX = base64url.baseEncode(uncompressed.subarray(1, 33));
|
|
26
|
+
const epkY = base64url.baseEncode(uncompressed.subarray(33, 65));
|
|
27
|
+
// 2. Build protected header
|
|
28
|
+
const header = {
|
|
29
|
+
alg: 'ECDH-ES',
|
|
30
|
+
enc: 'A256GCM',
|
|
31
|
+
epk: {
|
|
32
|
+
kty: 'EC',
|
|
33
|
+
crv: 'secp256k1',
|
|
34
|
+
x: epkX,
|
|
35
|
+
y: epkY,
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
const headerJson = JSON.stringify(header);
|
|
39
|
+
const headerB64 = base64url.baseEncode(ENCODER.encode(headerJson));
|
|
40
|
+
// 3. ECDH key agreement: ephemeral private + recipient public
|
|
41
|
+
const recipientPubBytes = jwkToCompressedBytes(recipientPubKey);
|
|
42
|
+
const sharedSecret = secp.getSharedSecret(ephemeralPrivKey, recipientPubBytes);
|
|
43
|
+
// 4. Derive CEK via Concat KDF (RFC 7518 §4.6.2)
|
|
44
|
+
// For ECDH-ES (direct), algorithmId = enc value
|
|
45
|
+
const cek = concatKdf(sharedSecret.slice(1), 256, 'A256GCM');
|
|
46
|
+
// 5. Generate random 96-bit IV
|
|
47
|
+
const iv = secp.utils.randomPrivateKey().slice(0, 12);
|
|
48
|
+
// 6. Encrypt with AES-256-GCM
|
|
49
|
+
// AAD = ASCII bytes of the base64url-encoded protected header
|
|
50
|
+
const aad = ENCODER.encode(headerB64);
|
|
51
|
+
const cipher = gcm(cek, iv, aad);
|
|
52
|
+
const encrypted = cipher.encrypt(plaintext); // returns ciphertext || tag
|
|
53
|
+
// 7. Split ciphertext and tag (tag is last 16 bytes)
|
|
54
|
+
const ciphertext = encrypted.slice(0, encrypted.length - 16);
|
|
55
|
+
const tag = encrypted.slice(encrypted.length - 16);
|
|
56
|
+
// 8. Assemble JWE Compact: header.encryptedKey.iv.ciphertext.tag
|
|
57
|
+
// For ECDH-ES (direct), encrypted key is empty
|
|
58
|
+
return [
|
|
59
|
+
headerB64,
|
|
60
|
+
'', // empty encrypted key
|
|
61
|
+
base64url.baseEncode(iv),
|
|
62
|
+
base64url.baseEncode(ciphertext),
|
|
63
|
+
base64url.baseEncode(tag),
|
|
64
|
+
].join('.');
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Parse and decrypt a JWE Compact Serialization string.
|
|
68
|
+
*
|
|
69
|
+
* @param recipientPrivKey - Recipient's private key (secp256k1 JWK)
|
|
70
|
+
* @param jweCompact - The JWE Compact string to decrypt
|
|
71
|
+
* @returns Decrypted plaintext
|
|
72
|
+
*/
|
|
73
|
+
export function parseJweCompact(recipientPrivKey, jweCompact) {
|
|
74
|
+
// 1. Split into 5 parts
|
|
75
|
+
const parts = jweCompact.split('.');
|
|
76
|
+
if (parts.length !== 5) {
|
|
77
|
+
throw new Error('Invalid JWE Compact: expected 5 segments');
|
|
78
|
+
}
|
|
79
|
+
const [headerB64, , ivB64, ciphertextB64, tagB64] = parts;
|
|
80
|
+
// 2. Parse protected header
|
|
81
|
+
const headerJson = DECODER.decode(base64url.baseDecode(headerB64));
|
|
82
|
+
const header = JSON.parse(headerJson);
|
|
83
|
+
if (header.alg !== 'ECDH-ES') {
|
|
84
|
+
throw new Error(`Unsupported JWE alg: ${header.alg}`);
|
|
85
|
+
}
|
|
86
|
+
if (header.enc !== 'A256GCM') {
|
|
87
|
+
throw new Error(`Unsupported JWE enc: ${header.enc}`);
|
|
88
|
+
}
|
|
89
|
+
// 3. Reconstruct ephemeral public key from header
|
|
90
|
+
const epk = header.epk;
|
|
91
|
+
const ephemeralPubBytes = jwkToCompressedBytes(epk);
|
|
92
|
+
// 4. ECDH key agreement: recipient private + ephemeral public
|
|
93
|
+
const recipientPrivBytes = base64url.baseDecode(recipientPrivKey.d);
|
|
94
|
+
const sharedSecret = secp.getSharedSecret(recipientPrivBytes, ephemeralPubBytes);
|
|
95
|
+
// 5. Derive CEK via Concat KDF
|
|
96
|
+
const cek = concatKdf(sharedSecret.slice(1), 256, 'A256GCM');
|
|
97
|
+
// 6. Decrypt with AES-256-GCM
|
|
98
|
+
const iv = base64url.baseDecode(ivB64);
|
|
99
|
+
const ciphertext = base64url.baseDecode(ciphertextB64);
|
|
100
|
+
const tag = base64url.baseDecode(tagB64);
|
|
101
|
+
// Reassemble ciphertext || tag for @noble/ciphers GCM
|
|
102
|
+
const encrypted = new Uint8Array(ciphertext.length + tag.length);
|
|
103
|
+
encrypted.set(ciphertext, 0);
|
|
104
|
+
encrypted.set(tag, ciphertext.length);
|
|
105
|
+
const aad = ENCODER.encode(headerB64);
|
|
106
|
+
const cipher = gcm(cek, iv, aad);
|
|
107
|
+
return cipher.decrypt(encrypted);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Detect whether a string is a JWE Compact Serialization.
|
|
111
|
+
*/
|
|
112
|
+
export function isJweCompact(ciphertext) {
|
|
113
|
+
return ciphertext.startsWith('eyJ') && ciphertext.split('.').length === 5;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Convert a JWK public key to compressed secp256k1 bytes.
|
|
117
|
+
*/
|
|
118
|
+
function jwkToCompressedBytes(jwk) {
|
|
119
|
+
const xBytes = base64url.baseDecode(jwk.x);
|
|
120
|
+
const yBytes = base64url.baseDecode(jwk.y);
|
|
121
|
+
const prefix = yBytes[yBytes.length - 1] % 2 === 0 ? 0x02 : 0x03;
|
|
122
|
+
return new Uint8Array([prefix, ...xBytes]);
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=jwe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwe.js","sourceRoot":"","sources":["../../src/jwe.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { pbkdf2Async } from '@noble/hashes/pbkdf2';
|
|
2
|
+
import { sha512 } from '@noble/hashes/sha512';
|
|
3
|
+
import { gcm } from '@noble/ciphers/aes';
|
|
4
|
+
import { randomBytes } from '@noble/hashes/utils';
|
|
5
|
+
const ENC_ITER_DEFAULT = 100_000;
|
|
6
|
+
const IV_LEN = 12;
|
|
7
|
+
const SALT_LEN = 16;
|
|
8
|
+
function getIterations() {
|
|
9
|
+
if (typeof process !== 'undefined' && process.env?.PBKDF2_ITERATIONS) {
|
|
10
|
+
const parsed = parseInt(process.env.PBKDF2_ITERATIONS, 10);
|
|
11
|
+
if (!isNaN(parsed) && parsed > 0) {
|
|
12
|
+
return parsed;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return ENC_ITER_DEFAULT;
|
|
16
|
+
}
|
|
17
|
+
export async function encryptWithPassphrase(plaintext, pass) {
|
|
18
|
+
const salt = randomBytes(SALT_LEN);
|
|
19
|
+
const iv = randomBytes(IV_LEN);
|
|
20
|
+
const key = await deriveKey(pass, salt);
|
|
21
|
+
const cipher = gcm(key, iv);
|
|
22
|
+
const ct = cipher.encrypt(new TextEncoder().encode(plaintext));
|
|
23
|
+
return { salt: b64(salt), iv: b64(iv), data: b64(ct) };
|
|
24
|
+
}
|
|
25
|
+
export async function decryptWithPassphrase(blob, pass) {
|
|
26
|
+
const salt = ub64(blob.salt);
|
|
27
|
+
const iv = ub64(blob.iv);
|
|
28
|
+
const data = ub64(blob.data);
|
|
29
|
+
const key = await deriveKey(pass, salt);
|
|
30
|
+
const cipher = gcm(key, iv);
|
|
31
|
+
const pt = cipher.decrypt(data);
|
|
32
|
+
return new TextDecoder().decode(pt);
|
|
33
|
+
}
|
|
34
|
+
const b64 = (buf) => {
|
|
35
|
+
return Buffer.from(buf).toString('base64');
|
|
36
|
+
};
|
|
37
|
+
const ub64 = (b64) => {
|
|
38
|
+
return new Uint8Array(Buffer.from(b64, 'base64'));
|
|
39
|
+
};
|
|
40
|
+
async function deriveKey(pass, salt) {
|
|
41
|
+
const enc = new TextEncoder();
|
|
42
|
+
return pbkdf2Async(sha512, enc.encode(pass), salt, { c: getIterations(), dkLen: 32 });
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=passphrase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passphrase.js","sourceRoot":"","sources":["../../src/passphrase.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,10 +12,12 @@ export default abstract class CipherBase implements Cipher {
|
|
|
12
12
|
hashJSON(json: unknown): string;
|
|
13
13
|
signHash(msgHash: string, privateJwk: EcdsaJwkPrivate): string;
|
|
14
14
|
verifySig(msgHash: string, sigHex: string, publicJwk: EcdsaJwkPublic): boolean;
|
|
15
|
-
encryptBytes(
|
|
16
|
-
decryptBytes(
|
|
17
|
-
encryptMessage(
|
|
18
|
-
decryptMessage(
|
|
15
|
+
encryptBytes(recipientPubKey: EcdsaJwkPublic, data: Uint8Array): string;
|
|
16
|
+
decryptBytes(recipientPrivKey: EcdsaJwkPrivate, ciphertext: string, legacyPubKey?: EcdsaJwkPublic): Uint8Array;
|
|
17
|
+
encryptMessage(recipientPubKey: EcdsaJwkPublic, message: string): string;
|
|
18
|
+
decryptMessage(recipientPrivKey: EcdsaJwkPrivate, ciphertext: string, legacyPubKey?: EcdsaJwkPublic): string;
|
|
19
|
+
decryptBytesLegacy(pubKey: EcdsaJwkPublic, privKey: EcdsaJwkPrivate, ciphertext: string): Uint8Array;
|
|
20
|
+
decryptMessageLegacy(pubKey: EcdsaJwkPublic, privKey: EcdsaJwkPrivate, ciphertext: string): string;
|
|
19
21
|
hasLeadingZeroBits(hexHash: string, bits: number): boolean;
|
|
20
22
|
addProofOfWork(obj: object, difficulty: number): object;
|
|
21
23
|
checkProofOfWork(obj: object): boolean;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Concat KDF (Single Step KDF) per NIST SP 800-56A and RFC 7518 §4.6.2.
|
|
3
|
+
*
|
|
4
|
+
* Derives a symmetric key from an ECDH shared secret for use in JWE.
|
|
5
|
+
*
|
|
6
|
+
* @param sharedSecret - The raw ECDH shared secret (Z)
|
|
7
|
+
* @param keyBitLength - Desired key length in bits (e.g. 128, 256)
|
|
8
|
+
* @param algorithmId - The "enc" value for ECDH-ES or "alg" for ECDH-ES+A*KW
|
|
9
|
+
* @param apu - Agreement PartyUInfo (typically empty)
|
|
10
|
+
* @param apv - Agreement PartyVInfo (typically empty)
|
|
11
|
+
* @returns Derived key as Uint8Array
|
|
12
|
+
*/
|
|
13
|
+
export declare function concatKdf(sharedSecret: Uint8Array, keyBitLength: number, algorithmId: string, apu?: Uint8Array, apv?: Uint8Array): Uint8Array;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { EcdsaJwkPublic, EcdsaJwkPrivate } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Build a JWE Compact Serialization string using ECDH-ES + A256GCM.
|
|
4
|
+
*
|
|
5
|
+
* Uses an ephemeral secp256k1 keypair for key agreement.
|
|
6
|
+
* The sender's identity key is NOT involved — only the recipient's public key.
|
|
7
|
+
*
|
|
8
|
+
* @param recipientPubKey - Recipient's public key (secp256k1 JWK)
|
|
9
|
+
* @param plaintext - Data to encrypt
|
|
10
|
+
* @returns JWE Compact string: header.encryptedKey.iv.ciphertext.tag
|
|
11
|
+
*/
|
|
12
|
+
export declare function buildJweCompact(recipientPubKey: EcdsaJwkPublic, plaintext: Uint8Array): string;
|
|
13
|
+
/**
|
|
14
|
+
* Parse and decrypt a JWE Compact Serialization string.
|
|
15
|
+
*
|
|
16
|
+
* @param recipientPrivKey - Recipient's private key (secp256k1 JWK)
|
|
17
|
+
* @param jweCompact - The JWE Compact string to decrypt
|
|
18
|
+
* @returns Decrypted plaintext
|
|
19
|
+
*/
|
|
20
|
+
export declare function parseJweCompact(recipientPrivKey: EcdsaJwkPrivate, jweCompact: string): Uint8Array;
|
|
21
|
+
/**
|
|
22
|
+
* Detect whether a string is a JWE Compact Serialization.
|
|
23
|
+
*/
|
|
24
|
+
export declare function isJweCompact(ciphertext: string): boolean;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare function encryptWithPassphrase(plaintext: string, pass: string): Promise<{
|
|
2
|
+
salt: string;
|
|
3
|
+
iv: string;
|
|
4
|
+
data: string;
|
|
5
|
+
}>;
|
|
6
|
+
export declare function decryptWithPassphrase(blob: {
|
|
7
|
+
salt: string;
|
|
8
|
+
iv: string;
|
|
9
|
+
data: string;
|
|
10
|
+
}, pass: string): Promise<string>;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -36,10 +36,12 @@ export interface Cipher {
|
|
|
36
36
|
hashJSON(obj: unknown): string;
|
|
37
37
|
signHash(msgHash: string, privateJwk: EcdsaJwkPrivate): string;
|
|
38
38
|
verifySig(msgHash: string, sigHex: string, publicJwk: EcdsaJwkPublic): boolean;
|
|
39
|
-
encryptBytes(
|
|
40
|
-
decryptBytes(
|
|
41
|
-
encryptMessage(
|
|
42
|
-
decryptMessage(
|
|
39
|
+
encryptBytes(recipientPubKey: EcdsaJwkPublic, data: Uint8Array): string;
|
|
40
|
+
decryptBytes(recipientPrivKey: EcdsaJwkPrivate, ciphertext: string, legacyPubKey?: EcdsaJwkPublic): Uint8Array;
|
|
41
|
+
encryptMessage(recipientPubKey: EcdsaJwkPublic, message: string): string;
|
|
42
|
+
decryptMessage(recipientPrivKey: EcdsaJwkPrivate, ciphertext: string, legacyPubKey?: EcdsaJwkPublic): string;
|
|
43
|
+
decryptBytesLegacy(pubKey: EcdsaJwkPublic, privKey: EcdsaJwkPrivate, ciphertext: string): Uint8Array;
|
|
44
|
+
decryptMessageLegacy(pubKey: EcdsaJwkPublic, privKey: EcdsaJwkPrivate, ciphertext: string): string;
|
|
43
45
|
generateRandomSalt(): string;
|
|
44
46
|
addProofOfWork(obj: unknown, difficulty: number): unknown;
|
|
45
47
|
checkProofOfWork(obj: unknown): boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@didcid/cipher",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Archon cipher lib",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/cjs/cipher-web.cjs",
|
|
@@ -40,6 +40,11 @@
|
|
|
40
40
|
"require": "./dist/cjs/cipher-web.cjs",
|
|
41
41
|
"types": "./dist/types/cipher-web.d.ts"
|
|
42
42
|
},
|
|
43
|
+
"./passphrase": {
|
|
44
|
+
"import": "./dist/esm/passphrase.js",
|
|
45
|
+
"require": "./dist/cjs/passphrase.cjs",
|
|
46
|
+
"types": "./dist/types/passphrase.d.ts"
|
|
47
|
+
},
|
|
43
48
|
"./types": {
|
|
44
49
|
"types": "./dist/types/types.d.ts"
|
|
45
50
|
}
|
|
@@ -52,6 +57,9 @@
|
|
|
52
57
|
"web": [
|
|
53
58
|
"./dist/types/cipher-web.d.ts"
|
|
54
59
|
],
|
|
60
|
+
"passphrase": [
|
|
61
|
+
"./dist/types/passphrase.d.ts"
|
|
62
|
+
],
|
|
55
63
|
"types": [
|
|
56
64
|
"./dist/types/types.d.ts"
|
|
57
65
|
]
|
|
@@ -81,5 +89,5 @@
|
|
|
81
89
|
"type": "git",
|
|
82
90
|
"url": "git+https://github.com/archetech/archon.git"
|
|
83
91
|
},
|
|
84
|
-
"gitHead": "
|
|
92
|
+
"gitHead": "4692cc18e1377cafc96aaf7a55cd969a0b09b77c"
|
|
85
93
|
}
|