@interop/minimal-cipher 7.4.0 → 7.5.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/README.md
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
[](https://github.com/interop-alliance/minimal-cipher/actions?query=workflow%3A%22CI%22)
|
|
4
4
|
[](https://npm.im/@interop/minimal-cipher)
|
|
5
5
|
|
|
6
|
-
Minimal encryption/decryption [JWE](https://tools.ietf.org/html/rfc7516)
|
|
7
|
-
library, secure algs only,
|
|
6
|
+
> Minimal TypeScript/JS encryption/decryption [JWE](https://tools.ietf.org/html/rfc7516)
|
|
7
|
+
library, secure algs only, for Node.js, browsers and React Native.
|
|
8
8
|
|
|
9
9
|
## Table of Contents
|
|
10
10
|
|
|
@@ -123,9 +123,10 @@ import { X25519KeyAgreementKey2020 } from '@interop/x25519-key-agreement-key'
|
|
|
123
123
|
import { Ed25519VerificationKey } from '@interop/ed25519-verification-key'
|
|
124
124
|
const keyPair = await Ed25519VerificationKey.generate()
|
|
125
125
|
|
|
126
|
-
const keyAgreementKey =
|
|
127
|
-
|
|
128
|
-
|
|
126
|
+
const keyAgreementKey =
|
|
127
|
+
X25519KeyAgreementKey2020.fromEd25519VerificationKey2020({
|
|
128
|
+
keyPair
|
|
129
|
+
})
|
|
129
130
|
// If the source key pair didn't have a controller set, don't forget to set one:
|
|
130
131
|
keyAgreementKey.controller = did // The controller's DID
|
|
131
132
|
keyAgreementKey.id = `${did}#${keyAgreementKey.fingerprint()}`
|
|
@@ -136,9 +137,10 @@ const authnKey = didDoc.getVerificationMethod({
|
|
|
136
137
|
proofPurpose: 'authentication'
|
|
137
138
|
})
|
|
138
139
|
const edKeyPair = await Ed25519VerificationKey.from(authnKey)
|
|
139
|
-
const keyAgreementKey =
|
|
140
|
-
|
|
141
|
-
|
|
140
|
+
const keyAgreementKey =
|
|
141
|
+
X25519KeyAgreementKey2020.fromEd25519VerificationKey2020({
|
|
142
|
+
keyPair: edKeyPair
|
|
143
|
+
})
|
|
142
144
|
|
|
143
145
|
const recipient = {
|
|
144
146
|
header: {
|
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import type { KEK as KEKInterface } from '../types.js';
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Creates a KEK, selecting the backend by capability: the WebCrypto `AES-KW`
|
|
4
|
+
* path when the runtime provides the key-wrap ops, otherwise the pure-JS
|
|
5
|
+
* RFC 3394 fallback. Both backends produce identical wrapped bytes.
|
|
6
|
+
*
|
|
7
|
+
* @param {object} options - The options to use.
|
|
8
|
+
* @param {Uint8Array} options.keyData - The 256-bit KEK material.
|
|
9
|
+
* @param {Crypto} [options.crypto] - WebCrypto instance to probe and use;
|
|
10
|
+
* defaults to the module's WebCrypto. Overridable for testing the fallback.
|
|
11
|
+
*
|
|
12
|
+
* @returns {Promise<KEKInterface>} - The KEK backend.
|
|
13
|
+
*/
|
|
14
|
+
export declare function createKek({ keyData, crypto: cryptoObj }: {
|
|
3
15
|
keyData: Uint8Array;
|
|
16
|
+
crypto?: Crypto;
|
|
4
17
|
}): Promise<KEKInterface>;
|
|
5
18
|
//# sourceMappingURL=aeskw.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aeskw.d.ts","sourceRoot":"","sources":["../../src/algorithms/aeskw.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"aeskw.d.ts","sourceRoot":"","sources":["../../src/algorithms/aeskw.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,GAAG,IAAI,YAAY,EAAE,MAAM,aAAa,CAAA;AA0KtD;;;;;;;;;;;GAWG;AACH,wBAAsB,SAAS,CAAC,EAC9B,OAAO,EACP,MAAM,EAAE,SAAkB,EAC3B,EAAE;IACD,OAAO,EAAE,UAAU,CAAA;IACnB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,GAAG,OAAO,CAAC,YAAY,CAAC,CAaxB"}
|
package/dist/algorithms/aeskw.js
CHANGED
|
@@ -1,8 +1,28 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Copyright (c) 2019-2026 Digital Bazaar, Inc.
|
|
3
3
|
*/
|
|
4
|
+
import { aeskw } from '@noble/ciphers/aes.js';
|
|
4
5
|
import { base64url } from '../baseX.js';
|
|
5
6
|
import crypto from '../crypto.js';
|
|
7
|
+
/**
|
|
8
|
+
* Feature-detects whether the given WebCrypto instance provides the AES-KW
|
|
9
|
+
* key-wrap subset. Browsers and Node (>=24) do; React Native / Hermes shims
|
|
10
|
+
* that only expose `subtle.digest` do not, so we fall back to the pure-JS
|
|
11
|
+
* RFC 3394 backend below.
|
|
12
|
+
*
|
|
13
|
+
* @param {Crypto} [cryptoObj] - A WebCrypto instance to probe.
|
|
14
|
+
*
|
|
15
|
+
* @returns {boolean} - True when `importKey`, `wrapKey`, `unwrapKey`, and
|
|
16
|
+
* `exportKey` are all available.
|
|
17
|
+
*/
|
|
18
|
+
function hasWebCryptoKeyWrap(cryptoObj) {
|
|
19
|
+
const subtle = cryptoObj?.subtle;
|
|
20
|
+
return !!(subtle &&
|
|
21
|
+
typeof subtle.importKey === 'function' &&
|
|
22
|
+
typeof subtle.wrapKey === 'function' &&
|
|
23
|
+
typeof subtle.unwrapKey === 'function' &&
|
|
24
|
+
typeof subtle.exportKey === 'function');
|
|
25
|
+
}
|
|
6
26
|
class Kek {
|
|
7
27
|
// `CryptoKey` is the Web Crypto API key type, sourced from the DOM lib.
|
|
8
28
|
key;
|
|
@@ -61,9 +81,72 @@ class Kek {
|
|
|
61
81
|
}
|
|
62
82
|
}
|
|
63
83
|
}
|
|
64
|
-
|
|
84
|
+
/**
|
|
85
|
+
* Pure-JS RFC 3394 AES Key Wrap (A256KW) backend, used as a fallback on
|
|
86
|
+
* runtimes such as React Native / Hermes whose WebCrypto lacks the key-wrap
|
|
87
|
+
* ops. Uses `@noble/ciphers`' `aeskw`, which implements RFC 3394 with the
|
|
88
|
+
* default IV `A6A6A6A6A6A6A6A6` and therefore produces byte-identical wrapped
|
|
89
|
+
* output to WebCrypto `AES-KW` for the same KEK and key material.
|
|
90
|
+
*/
|
|
91
|
+
class PureJsKek {
|
|
92
|
+
_keyData;
|
|
93
|
+
algorithm;
|
|
94
|
+
constructor(keyData) {
|
|
95
|
+
this._keyData = keyData;
|
|
96
|
+
this.algorithm = { name: 'A256KW' };
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Wraps a cryptographic key.
|
|
100
|
+
*
|
|
101
|
+
* @param {object} options - The options to use.
|
|
102
|
+
* @param {Uint8Array} options.unwrappedKey - The key material as a
|
|
103
|
+
* `Uint8Array`.
|
|
104
|
+
*
|
|
105
|
+
* @returns {Promise<string>} - The base64url-encoded wrapped key bytes.
|
|
106
|
+
*/
|
|
107
|
+
async wrapKey({ unwrappedKey }) {
|
|
108
|
+
const wrappedKey = aeskw(this._keyData).encrypt(unwrappedKey);
|
|
109
|
+
return base64url.encode(wrappedKey);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Unwraps a cryptographic key.
|
|
113
|
+
*
|
|
114
|
+
* @param {object} options - The options to use.
|
|
115
|
+
* @param {string} options.wrappedKey - The wrapped key material as a
|
|
116
|
+
* base64url-encoded string.
|
|
117
|
+
*
|
|
118
|
+
* @returns {Promise<Uint8Array>} - Resolves to the key bytes or null if
|
|
119
|
+
* the unwrapping fails because the key does not match.
|
|
120
|
+
*/
|
|
121
|
+
async unwrapKey({ wrappedKey }) {
|
|
122
|
+
const wrappedKeyBytes = base64url.decode(wrappedKey);
|
|
123
|
+
try {
|
|
124
|
+
return aeskw(this._keyData).decrypt(wrappedKeyBytes);
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
// integrity check failed -- KEK does not match
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Creates a KEK, selecting the backend by capability: the WebCrypto `AES-KW`
|
|
134
|
+
* path when the runtime provides the key-wrap ops, otherwise the pure-JS
|
|
135
|
+
* RFC 3394 fallback. Both backends produce identical wrapped bytes.
|
|
136
|
+
*
|
|
137
|
+
* @param {object} options - The options to use.
|
|
138
|
+
* @param {Uint8Array} options.keyData - The 256-bit KEK material.
|
|
139
|
+
* @param {Crypto} [options.crypto] - WebCrypto instance to probe and use;
|
|
140
|
+
* defaults to the module's WebCrypto. Overridable for testing the fallback.
|
|
141
|
+
*
|
|
142
|
+
* @returns {Promise<KEKInterface>} - The KEK backend.
|
|
143
|
+
*/
|
|
144
|
+
export async function createKek({ keyData, crypto: cryptoObj = crypto }) {
|
|
145
|
+
if (!hasWebCryptoKeyWrap(cryptoObj)) {
|
|
146
|
+
return new PureJsKek(keyData);
|
|
147
|
+
}
|
|
65
148
|
const extractable = true;
|
|
66
|
-
const key = await
|
|
149
|
+
const key = await cryptoObj.subtle.importKey('raw', keyData, { name: 'AES-KW', length: 256 }, extractable, ['wrapKey', 'unwrapKey']);
|
|
67
150
|
return new Kek(key);
|
|
68
151
|
}
|
|
69
152
|
//# sourceMappingURL=aeskw.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aeskw.js","sourceRoot":"","sources":["../../src/algorithms/aeskw.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,MAAM,MAAM,cAAc,CAAA;AAGjC,MAAM,GAAG;IACP,wEAAwE;IACxE,GAAG,CAAW;IACd,SAAS,CAAkB;IAE3B,YAAY,GAAc;QACxB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAA;QACd,IAAI,CAAC,SAAS,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAA;IACrC,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,OAAO,CAAC,EACZ,YAAY,EAGb;QACC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAA;QACpB,uEAAuE;QACvE,MAAM,WAAW,GAAG,IAAI,CAAA;QAExB,MAAM,kBAAkB,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CACtD,KAAK,EACL,YAA4B,EAC5B,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE;QAChC,qEAAqE;QACrE,qEAAqE;QACrE,aAAa;QACb,WAAW,EACX,CAAC,SAAS,CAAC,CACZ,CAAA;QACD,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,CAC5C,KAAK,EACL,kBAAkB,EAClB,GAAG,EACH,GAAG,CAAC,SAAS,CACd,CAAA;QACD,OAAO,SAAS,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC,CAAA;IACrD,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,SAAS,CAAC,EACd,UAAU,EAGX;QACC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAA;QACpB,uEAAuE;QACvE,MAAM,eAAe,GAAG,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;QACpD,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,IAAI,CAAA;YACxB,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CACvC,KAAK,EACL,eAA+B,EAC/B,GAAG,EACH,GAAG,CAAC,SAAS;YACb,oEAAoE;YACpE,gEAAgE;YAChE,EAAE,IAAI,EAAE,SAAS,EAAE,EACnB,WAAW,EACX,CAAC,SAAS,CAAC,CACZ,CAAA;YACD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;YAC1D,OAAO,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAA;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,wBAAwB;YACxB,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,EAC9B,OAAO,
|
|
1
|
+
{"version":3,"file":"aeskw.js","sourceRoot":"","sources":["../../src/algorithms/aeskw.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@interop/minimal-cipher",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.5.0",
|
|
4
4
|
"description": "Minimal encryption/decryption JWE library.",
|
|
5
5
|
"license": "BSD-3-Clause",
|
|
6
6
|
"type": "module",
|
|
@@ -40,8 +40,9 @@
|
|
|
40
40
|
"test:coverage": "vitest run --coverage"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@interop/data-integrity-core": "^8.
|
|
44
|
-
"@interop/ecdsa-multikey": "^2.3.
|
|
43
|
+
"@interop/data-integrity-core": "^8.1.0",
|
|
44
|
+
"@interop/ecdsa-multikey": "^2.3.2",
|
|
45
|
+
"@noble/ciphers": "^2.2.0",
|
|
45
46
|
"@noble/curves": "^2.2.0",
|
|
46
47
|
"@scure/base": "^2.2.0",
|
|
47
48
|
"@stablelib/chacha": "^2.0.1",
|
|
@@ -49,9 +50,9 @@
|
|
|
49
50
|
},
|
|
50
51
|
"devDependencies": {
|
|
51
52
|
"@eslint/js": "^10.0.1",
|
|
52
|
-
"@interop/did-io": "^4.0.
|
|
53
|
-
"@interop/did-method-key": "^7.3.
|
|
54
|
-
"@interop/ed25519-verification-key": "^8.0.
|
|
53
|
+
"@interop/did-io": "^4.0.6",
|
|
54
|
+
"@interop/did-method-key": "^7.3.3",
|
|
55
|
+
"@interop/ed25519-verification-key": "^8.0.2",
|
|
55
56
|
"@interop/x25519-key-agreement-key": "^5.1.0",
|
|
56
57
|
"@playwright/test": "^1.60.0",
|
|
57
58
|
"@types/node": "^25.9.1",
|