@matter/nodejs 0.16.0-alpha.0-20250821-dd03e1003 → 0.16.0-alpha.0-20250826-531401faa
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/crypto/NodeJsCrypto.d.ts +6 -22
- package/dist/cjs/crypto/NodeJsCrypto.d.ts.map +1 -1
- package/dist/cjs/crypto/NodeJsCrypto.js +3 -133
- package/dist/cjs/crypto/NodeJsCrypto.js.map +1 -1
- package/dist/esm/crypto/NodeJsCrypto.d.ts +6 -22
- package/dist/esm/crypto/NodeJsCrypto.d.ts.map +1 -1
- package/dist/esm/crypto/NodeJsCrypto.js +4 -147
- package/dist/esm/crypto/NodeJsCrypto.js.map +1 -1
- package/package.json +10 -10
- package/src/crypto/NodeJsCrypto.ts +7 -176
|
@@ -3,27 +3,11 @@
|
|
|
3
3
|
* Copyright 2022-2025 Matter.js Authors
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
ecdhGeneratePublicKey(): {
|
|
13
|
-
publicKey: Bytes;
|
|
14
|
-
ecdh: any;
|
|
15
|
-
};
|
|
16
|
-
ecdhGeneratePublicKeyAndSecret(peerPublicKey: Bytes): {
|
|
17
|
-
publicKey: Bytes;
|
|
18
|
-
sharedSecret: Bytes;
|
|
19
|
-
};
|
|
20
|
-
computeSha256(data: Bytes | Bytes[]): Bytes;
|
|
21
|
-
createPbkdf2Key(secret: Bytes, salt: Bytes, iteration: number, keyLength: number): Promise<Bytes>;
|
|
22
|
-
createHkdfKey(secret: Bytes, salt: Bytes, info: Bytes, length?: number): Promise<Bytes>;
|
|
23
|
-
signHmac(key: Bytes, data: Bytes): Bytes;
|
|
24
|
-
signEcdsa(privateKey: JsonWebKey, data: Bytes | Bytes[], dsaEncoding?: CryptoDsaEncoding): Bytes;
|
|
25
|
-
verifyEcdsa(publicKey: JsonWebKey, data: Bytes, signature: Bytes, dsaEncoding?: CryptoDsaEncoding): void;
|
|
26
|
-
createKeyPair(): PrivateKey;
|
|
27
|
-
generateDhSecret(key: PrivateKey, peerKey: PublicKey): Bytes;
|
|
6
|
+
import { NodeJsStyleCrypto } from "#general";
|
|
7
|
+
/**
|
|
8
|
+
* Node.js-based crypto implementation.
|
|
9
|
+
*/
|
|
10
|
+
export declare class NodeJsCrypto extends NodeJsStyleCrypto {
|
|
11
|
+
constructor();
|
|
28
12
|
}
|
|
29
13
|
//# sourceMappingURL=NodeJsCrypto.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NodeJsCrypto.d.ts","sourceRoot":"","sources":["../../../src/crypto/NodeJsCrypto.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"NodeJsCrypto.d.ts","sourceRoot":"","sources":["../../../src/crypto/NodeJsCrypto.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAG7C;;GAEG;AACH,qBAAa,YAAa,SAAQ,iBAAiB;;CAIlD"}
|
|
@@ -38,139 +38,9 @@ var crypto = __toESM(require("node:crypto"), 1);
|
|
|
38
38
|
* Copyright 2022-2025 Matter.js Authors
|
|
39
39
|
* SPDX-License-Identifier: Apache-2.0
|
|
40
40
|
*/
|
|
41
|
-
class NodeJsCrypto extends import_general.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const cipher = crypto.createCipheriv(import_general.CRYPTO_ENCRYPT_ALGORITHM, import_general.Bytes.of(key), import_general.Bytes.of(nonce), {
|
|
45
|
-
authTagLength: import_general.CRYPTO_AUTH_TAG_LENGTH
|
|
46
|
-
});
|
|
47
|
-
if (aad !== void 0) {
|
|
48
|
-
cipher.setAAD(import_general.Bytes.of(aad), { plaintextLength: data.byteLength });
|
|
49
|
-
}
|
|
50
|
-
const encrypted = cipher.update(import_general.Bytes.of(data));
|
|
51
|
-
cipher.final();
|
|
52
|
-
return import_general.Bytes.concat(import_general.Bytes.of(encrypted), import_general.Bytes.of(cipher.getAuthTag()));
|
|
53
|
-
}
|
|
54
|
-
decrypt(key, encrypted, nonce, aad) {
|
|
55
|
-
const cipher = crypto.createDecipheriv(import_general.CRYPTO_ENCRYPT_ALGORITHM, import_general.Bytes.of(key), import_general.Bytes.of(nonce), {
|
|
56
|
-
authTagLength: import_general.CRYPTO_AUTH_TAG_LENGTH
|
|
57
|
-
});
|
|
58
|
-
const data = import_general.Bytes.of(encrypted);
|
|
59
|
-
const plaintextLength = data.length - import_general.CRYPTO_AUTH_TAG_LENGTH;
|
|
60
|
-
if (aad !== void 0) {
|
|
61
|
-
cipher.setAAD(import_general.Bytes.of(aad), { plaintextLength });
|
|
62
|
-
}
|
|
63
|
-
cipher.setAuthTag(data.slice(plaintextLength));
|
|
64
|
-
const result = cipher.update(data.slice(0, plaintextLength));
|
|
65
|
-
try {
|
|
66
|
-
cipher.final();
|
|
67
|
-
} catch (e) {
|
|
68
|
-
throw new import_general.CryptoDecryptError(`${import_general.CRYPTO_ENCRYPT_ALGORITHM} decryption failed: ${(0, import_general.asError)(e).message}`);
|
|
69
|
-
}
|
|
70
|
-
return new Uint8Array(result);
|
|
71
|
-
}
|
|
72
|
-
randomBytes(length) {
|
|
73
|
-
return new Uint8Array(crypto.randomBytes(length));
|
|
74
|
-
}
|
|
75
|
-
ecdhGeneratePublicKey() {
|
|
76
|
-
const ecdh = crypto.createECDH(import_general.CRYPTO_EC_CURVE);
|
|
77
|
-
ecdh.generateKeys();
|
|
78
|
-
return { publicKey: new Uint8Array(ecdh.getPublicKey()), ecdh };
|
|
79
|
-
}
|
|
80
|
-
ecdhGeneratePublicKeyAndSecret(peerPublicKey) {
|
|
81
|
-
const ecdh = crypto.createECDH(import_general.CRYPTO_EC_CURVE);
|
|
82
|
-
ecdh.generateKeys();
|
|
83
|
-
return {
|
|
84
|
-
publicKey: new Uint8Array(ecdh.getPublicKey()),
|
|
85
|
-
sharedSecret: new Uint8Array(ecdh.computeSecret(import_general.Bytes.of(peerPublicKey)))
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
computeSha256(data) {
|
|
89
|
-
const hasher = crypto.createHash(import_general.CRYPTO_HASH_ALGORITHM);
|
|
90
|
-
if (Array.isArray(data)) {
|
|
91
|
-
data.forEach((chunk) => hasher.update(import_general.Bytes.of(chunk)));
|
|
92
|
-
} else {
|
|
93
|
-
hasher.update(import_general.Bytes.of(data));
|
|
94
|
-
}
|
|
95
|
-
return new Uint8Array(hasher.digest());
|
|
96
|
-
}
|
|
97
|
-
createPbkdf2Key(secret, salt, iteration, keyLength) {
|
|
98
|
-
return new Promise((resolver, rejecter) => {
|
|
99
|
-
crypto.pbkdf2(
|
|
100
|
-
import_general.Bytes.of(secret),
|
|
101
|
-
import_general.Bytes.of(salt),
|
|
102
|
-
iteration,
|
|
103
|
-
keyLength,
|
|
104
|
-
import_general.CRYPTO_HASH_ALGORITHM,
|
|
105
|
-
(error, key) => {
|
|
106
|
-
if (error !== null) rejecter(error);
|
|
107
|
-
resolver(new Uint8Array(key));
|
|
108
|
-
}
|
|
109
|
-
);
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
createHkdfKey(secret, salt, info, length = import_general.CRYPTO_SYMMETRIC_KEY_LENGTH) {
|
|
113
|
-
return new Promise((resolver, rejecter) => {
|
|
114
|
-
crypto.hkdf(
|
|
115
|
-
import_general.CRYPTO_HASH_ALGORITHM,
|
|
116
|
-
import_general.Bytes.of(secret),
|
|
117
|
-
import_general.Bytes.of(salt),
|
|
118
|
-
import_general.Bytes.of(info),
|
|
119
|
-
length,
|
|
120
|
-
(error, key) => {
|
|
121
|
-
if (error !== null) rejecter(error);
|
|
122
|
-
resolver(new Uint8Array(key));
|
|
123
|
-
}
|
|
124
|
-
);
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
signHmac(key, data) {
|
|
128
|
-
const hmac = crypto.createHmac(import_general.CRYPTO_HASH_ALGORITHM, import_general.Bytes.of(key));
|
|
129
|
-
hmac.update(import_general.Bytes.of(data));
|
|
130
|
-
return new Uint8Array(hmac.digest());
|
|
131
|
-
}
|
|
132
|
-
signEcdsa(privateKey, data, dsaEncoding = "ieee-p1363") {
|
|
133
|
-
const signer = crypto.createSign(import_general.CRYPTO_HASH_ALGORITHM);
|
|
134
|
-
if (Array.isArray(data)) {
|
|
135
|
-
data.forEach((chunk) => signer.update(import_general.Bytes.of(chunk)));
|
|
136
|
-
} else {
|
|
137
|
-
signer.update(import_general.Bytes.of(data));
|
|
138
|
-
}
|
|
139
|
-
return new Uint8Array(
|
|
140
|
-
signer.sign({
|
|
141
|
-
key: privateKey,
|
|
142
|
-
format: "jwk",
|
|
143
|
-
type: "pkcs8",
|
|
144
|
-
dsaEncoding
|
|
145
|
-
})
|
|
146
|
-
);
|
|
147
|
-
}
|
|
148
|
-
verifyEcdsa(publicKey, data, signature, dsaEncoding = "ieee-p1363") {
|
|
149
|
-
const verifier = crypto.createVerify(import_general.CRYPTO_HASH_ALGORITHM);
|
|
150
|
-
verifier.update(import_general.Bytes.of(data));
|
|
151
|
-
const success = verifier.verify(
|
|
152
|
-
{
|
|
153
|
-
key: publicKey,
|
|
154
|
-
format: "jwk",
|
|
155
|
-
type: "spki",
|
|
156
|
-
dsaEncoding
|
|
157
|
-
},
|
|
158
|
-
import_general.Bytes.of(signature)
|
|
159
|
-
);
|
|
160
|
-
if (!success) throw new import_general.CryptoVerifyError("Signature verification failed");
|
|
161
|
-
}
|
|
162
|
-
createKeyPair() {
|
|
163
|
-
const ecdh = crypto.createECDH(import_general.CRYPTO_EC_CURVE);
|
|
164
|
-
ecdh.generateKeys();
|
|
165
|
-
const privateKey = new Uint8Array(import_general.CRYPTO_EC_KEY_BYTES);
|
|
166
|
-
const nodePrivateKey = ecdh.getPrivateKey();
|
|
167
|
-
privateKey.set(nodePrivateKey, import_general.CRYPTO_EC_KEY_BYTES - nodePrivateKey.length);
|
|
168
|
-
return (0, import_general.PrivateKey)(privateKey, { publicKey: import_general.Bytes.of(ecdh.getPublicKey()) });
|
|
169
|
-
}
|
|
170
|
-
generateDhSecret(key, peerKey) {
|
|
171
|
-
const ecdh = crypto.createECDH(import_general.CRYPTO_EC_CURVE);
|
|
172
|
-
ecdh.setPrivateKey(import_general.Bytes.of(key.privateBits));
|
|
173
|
-
return import_general.Bytes.of(ecdh.computeSecret(import_general.Bytes.of(peerKey.publicBits)));
|
|
41
|
+
class NodeJsCrypto extends import_general.NodeJsStyleCrypto {
|
|
42
|
+
constructor() {
|
|
43
|
+
super(crypto);
|
|
174
44
|
}
|
|
175
45
|
}
|
|
176
46
|
//# sourceMappingURL=NodeJsCrypto.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/crypto/NodeJsCrypto.ts"],
|
|
4
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,
|
|
4
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,qBAAkC;AAClC,aAAwB;AAPxB;AAAA;AAAA;AAAA;AAAA;AAYO,MAAM,qBAAqB,iCAAkB;AAAA,EAChD,cAAc;AACV,UAAM,MAAM;AAAA,EAChB;AACJ;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -3,27 +3,11 @@
|
|
|
3
3
|
* Copyright 2022-2025 Matter.js Authors
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
ecdhGeneratePublicKey(): {
|
|
13
|
-
publicKey: Bytes;
|
|
14
|
-
ecdh: any;
|
|
15
|
-
};
|
|
16
|
-
ecdhGeneratePublicKeyAndSecret(peerPublicKey: Bytes): {
|
|
17
|
-
publicKey: Bytes;
|
|
18
|
-
sharedSecret: Bytes;
|
|
19
|
-
};
|
|
20
|
-
computeSha256(data: Bytes | Bytes[]): Bytes;
|
|
21
|
-
createPbkdf2Key(secret: Bytes, salt: Bytes, iteration: number, keyLength: number): Promise<Bytes>;
|
|
22
|
-
createHkdfKey(secret: Bytes, salt: Bytes, info: Bytes, length?: number): Promise<Bytes>;
|
|
23
|
-
signHmac(key: Bytes, data: Bytes): Bytes;
|
|
24
|
-
signEcdsa(privateKey: JsonWebKey, data: Bytes | Bytes[], dsaEncoding?: CryptoDsaEncoding): Bytes;
|
|
25
|
-
verifyEcdsa(publicKey: JsonWebKey, data: Bytes, signature: Bytes, dsaEncoding?: CryptoDsaEncoding): void;
|
|
26
|
-
createKeyPair(): PrivateKey;
|
|
27
|
-
generateDhSecret(key: PrivateKey, peerKey: PublicKey): Bytes;
|
|
6
|
+
import { NodeJsStyleCrypto } from "#general";
|
|
7
|
+
/**
|
|
8
|
+
* Node.js-based crypto implementation.
|
|
9
|
+
*/
|
|
10
|
+
export declare class NodeJsCrypto extends NodeJsStyleCrypto {
|
|
11
|
+
constructor();
|
|
28
12
|
}
|
|
29
13
|
//# sourceMappingURL=NodeJsCrypto.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NodeJsCrypto.d.ts","sourceRoot":"","sources":["../../../src/crypto/NodeJsCrypto.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"NodeJsCrypto.d.ts","sourceRoot":"","sources":["../../../src/crypto/NodeJsCrypto.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAG7C;;GAEG;AACH,qBAAa,YAAa,SAAQ,iBAAiB;;CAIlD"}
|
|
@@ -3,154 +3,11 @@
|
|
|
3
3
|
* Copyright 2022-2025 Matter.js Authors
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
7
|
-
Bytes,
|
|
8
|
-
CRYPTO_AUTH_TAG_LENGTH,
|
|
9
|
-
CRYPTO_EC_CURVE,
|
|
10
|
-
CRYPTO_EC_KEY_BYTES,
|
|
11
|
-
CRYPTO_ENCRYPT_ALGORITHM,
|
|
12
|
-
CRYPTO_HASH_ALGORITHM,
|
|
13
|
-
CRYPTO_SYMMETRIC_KEY_LENGTH,
|
|
14
|
-
Crypto,
|
|
15
|
-
CryptoDecryptError,
|
|
16
|
-
CryptoVerifyError,
|
|
17
|
-
PrivateKey,
|
|
18
|
-
asError
|
|
19
|
-
} from "#general";
|
|
6
|
+
import { NodeJsStyleCrypto } from "#general";
|
|
20
7
|
import * as crypto from "node:crypto";
|
|
21
|
-
class NodeJsCrypto extends
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const cipher = crypto.createCipheriv(CRYPTO_ENCRYPT_ALGORITHM, Bytes.of(key), Bytes.of(nonce), {
|
|
25
|
-
authTagLength: CRYPTO_AUTH_TAG_LENGTH
|
|
26
|
-
});
|
|
27
|
-
if (aad !== void 0) {
|
|
28
|
-
cipher.setAAD(Bytes.of(aad), { plaintextLength: data.byteLength });
|
|
29
|
-
}
|
|
30
|
-
const encrypted = cipher.update(Bytes.of(data));
|
|
31
|
-
cipher.final();
|
|
32
|
-
return Bytes.concat(Bytes.of(encrypted), Bytes.of(cipher.getAuthTag()));
|
|
33
|
-
}
|
|
34
|
-
decrypt(key, encrypted, nonce, aad) {
|
|
35
|
-
const cipher = crypto.createDecipheriv(CRYPTO_ENCRYPT_ALGORITHM, Bytes.of(key), Bytes.of(nonce), {
|
|
36
|
-
authTagLength: CRYPTO_AUTH_TAG_LENGTH
|
|
37
|
-
});
|
|
38
|
-
const data = Bytes.of(encrypted);
|
|
39
|
-
const plaintextLength = data.length - CRYPTO_AUTH_TAG_LENGTH;
|
|
40
|
-
if (aad !== void 0) {
|
|
41
|
-
cipher.setAAD(Bytes.of(aad), { plaintextLength });
|
|
42
|
-
}
|
|
43
|
-
cipher.setAuthTag(data.slice(plaintextLength));
|
|
44
|
-
const result = cipher.update(data.slice(0, plaintextLength));
|
|
45
|
-
try {
|
|
46
|
-
cipher.final();
|
|
47
|
-
} catch (e) {
|
|
48
|
-
throw new CryptoDecryptError(`${CRYPTO_ENCRYPT_ALGORITHM} decryption failed: ${asError(e).message}`);
|
|
49
|
-
}
|
|
50
|
-
return new Uint8Array(result);
|
|
51
|
-
}
|
|
52
|
-
randomBytes(length) {
|
|
53
|
-
return new Uint8Array(crypto.randomBytes(length));
|
|
54
|
-
}
|
|
55
|
-
ecdhGeneratePublicKey() {
|
|
56
|
-
const ecdh = crypto.createECDH(CRYPTO_EC_CURVE);
|
|
57
|
-
ecdh.generateKeys();
|
|
58
|
-
return { publicKey: new Uint8Array(ecdh.getPublicKey()), ecdh };
|
|
59
|
-
}
|
|
60
|
-
ecdhGeneratePublicKeyAndSecret(peerPublicKey) {
|
|
61
|
-
const ecdh = crypto.createECDH(CRYPTO_EC_CURVE);
|
|
62
|
-
ecdh.generateKeys();
|
|
63
|
-
return {
|
|
64
|
-
publicKey: new Uint8Array(ecdh.getPublicKey()),
|
|
65
|
-
sharedSecret: new Uint8Array(ecdh.computeSecret(Bytes.of(peerPublicKey)))
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
computeSha256(data) {
|
|
69
|
-
const hasher = crypto.createHash(CRYPTO_HASH_ALGORITHM);
|
|
70
|
-
if (Array.isArray(data)) {
|
|
71
|
-
data.forEach((chunk) => hasher.update(Bytes.of(chunk)));
|
|
72
|
-
} else {
|
|
73
|
-
hasher.update(Bytes.of(data));
|
|
74
|
-
}
|
|
75
|
-
return new Uint8Array(hasher.digest());
|
|
76
|
-
}
|
|
77
|
-
createPbkdf2Key(secret, salt, iteration, keyLength) {
|
|
78
|
-
return new Promise((resolver, rejecter) => {
|
|
79
|
-
crypto.pbkdf2(
|
|
80
|
-
Bytes.of(secret),
|
|
81
|
-
Bytes.of(salt),
|
|
82
|
-
iteration,
|
|
83
|
-
keyLength,
|
|
84
|
-
CRYPTO_HASH_ALGORITHM,
|
|
85
|
-
(error, key) => {
|
|
86
|
-
if (error !== null) rejecter(error);
|
|
87
|
-
resolver(new Uint8Array(key));
|
|
88
|
-
}
|
|
89
|
-
);
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
createHkdfKey(secret, salt, info, length = CRYPTO_SYMMETRIC_KEY_LENGTH) {
|
|
93
|
-
return new Promise((resolver, rejecter) => {
|
|
94
|
-
crypto.hkdf(
|
|
95
|
-
CRYPTO_HASH_ALGORITHM,
|
|
96
|
-
Bytes.of(secret),
|
|
97
|
-
Bytes.of(salt),
|
|
98
|
-
Bytes.of(info),
|
|
99
|
-
length,
|
|
100
|
-
(error, key) => {
|
|
101
|
-
if (error !== null) rejecter(error);
|
|
102
|
-
resolver(new Uint8Array(key));
|
|
103
|
-
}
|
|
104
|
-
);
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
signHmac(key, data) {
|
|
108
|
-
const hmac = crypto.createHmac(CRYPTO_HASH_ALGORITHM, Bytes.of(key));
|
|
109
|
-
hmac.update(Bytes.of(data));
|
|
110
|
-
return new Uint8Array(hmac.digest());
|
|
111
|
-
}
|
|
112
|
-
signEcdsa(privateKey, data, dsaEncoding = "ieee-p1363") {
|
|
113
|
-
const signer = crypto.createSign(CRYPTO_HASH_ALGORITHM);
|
|
114
|
-
if (Array.isArray(data)) {
|
|
115
|
-
data.forEach((chunk) => signer.update(Bytes.of(chunk)));
|
|
116
|
-
} else {
|
|
117
|
-
signer.update(Bytes.of(data));
|
|
118
|
-
}
|
|
119
|
-
return new Uint8Array(
|
|
120
|
-
signer.sign({
|
|
121
|
-
key: privateKey,
|
|
122
|
-
format: "jwk",
|
|
123
|
-
type: "pkcs8",
|
|
124
|
-
dsaEncoding
|
|
125
|
-
})
|
|
126
|
-
);
|
|
127
|
-
}
|
|
128
|
-
verifyEcdsa(publicKey, data, signature, dsaEncoding = "ieee-p1363") {
|
|
129
|
-
const verifier = crypto.createVerify(CRYPTO_HASH_ALGORITHM);
|
|
130
|
-
verifier.update(Bytes.of(data));
|
|
131
|
-
const success = verifier.verify(
|
|
132
|
-
{
|
|
133
|
-
key: publicKey,
|
|
134
|
-
format: "jwk",
|
|
135
|
-
type: "spki",
|
|
136
|
-
dsaEncoding
|
|
137
|
-
},
|
|
138
|
-
Bytes.of(signature)
|
|
139
|
-
);
|
|
140
|
-
if (!success) throw new CryptoVerifyError("Signature verification failed");
|
|
141
|
-
}
|
|
142
|
-
createKeyPair() {
|
|
143
|
-
const ecdh = crypto.createECDH(CRYPTO_EC_CURVE);
|
|
144
|
-
ecdh.generateKeys();
|
|
145
|
-
const privateKey = new Uint8Array(CRYPTO_EC_KEY_BYTES);
|
|
146
|
-
const nodePrivateKey = ecdh.getPrivateKey();
|
|
147
|
-
privateKey.set(nodePrivateKey, CRYPTO_EC_KEY_BYTES - nodePrivateKey.length);
|
|
148
|
-
return PrivateKey(privateKey, { publicKey: Bytes.of(ecdh.getPublicKey()) });
|
|
149
|
-
}
|
|
150
|
-
generateDhSecret(key, peerKey) {
|
|
151
|
-
const ecdh = crypto.createECDH(CRYPTO_EC_CURVE);
|
|
152
|
-
ecdh.setPrivateKey(Bytes.of(key.privateBits));
|
|
153
|
-
return Bytes.of(ecdh.computeSecret(Bytes.of(peerKey.publicBits)));
|
|
8
|
+
class NodeJsCrypto extends NodeJsStyleCrypto {
|
|
9
|
+
constructor() {
|
|
10
|
+
super(crypto);
|
|
154
11
|
}
|
|
155
12
|
}
|
|
156
13
|
export {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/crypto/NodeJsCrypto.ts"],
|
|
4
|
-
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAMA
|
|
4
|
+
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,SAAS,yBAAyB;AAClC,YAAY,YAAY;AAKjB,MAAM,qBAAqB,kBAAkB;AAAA,EAChD,cAAc;AACV,UAAM,MAAM;AAAA,EAChB;AACJ;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matter/nodejs",
|
|
3
|
-
"version": "0.16.0-alpha.0-
|
|
3
|
+
"version": "0.16.0-alpha.0-20250826-531401faa",
|
|
4
4
|
"description": "Node.js platform support for matter.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"iot",
|
|
@@ -44,17 +44,17 @@
|
|
|
44
44
|
"#*": "./src/*"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@matter/general": "0.16.0-alpha.0-
|
|
48
|
-
"@matter/node": "0.16.0-alpha.0-
|
|
49
|
-
"@matter/protocol": "0.16.0-alpha.0-
|
|
50
|
-
"@matter/types": "0.16.0-alpha.0-
|
|
47
|
+
"@matter/general": "0.16.0-alpha.0-20250826-531401faa",
|
|
48
|
+
"@matter/node": "0.16.0-alpha.0-20250826-531401faa",
|
|
49
|
+
"@matter/protocol": "0.16.0-alpha.0-20250826-531401faa",
|
|
50
|
+
"@matter/types": "0.16.0-alpha.0-20250826-531401faa"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"@matter/model": "0.16.0-alpha.0-
|
|
54
|
-
"@matter/protocol": "0.16.0-alpha.0-
|
|
55
|
-
"@matter/tools": "0.16.0-alpha.0-
|
|
56
|
-
"@matter/testing": "0.16.0-alpha.0-
|
|
57
|
-
"@project-chip/matter.js": "0.16.0-alpha.0-
|
|
53
|
+
"@matter/model": "0.16.0-alpha.0-20250826-531401faa",
|
|
54
|
+
"@matter/protocol": "0.16.0-alpha.0-20250826-531401faa",
|
|
55
|
+
"@matter/tools": "0.16.0-alpha.0-20250826-531401faa",
|
|
56
|
+
"@matter/testing": "0.16.0-alpha.0-20250826-531401faa",
|
|
57
|
+
"@project-chip/matter.js": "0.16.0-alpha.0-20250826-531401faa",
|
|
58
58
|
"@types/bytebuffer": "^5.0.49"
|
|
59
59
|
},
|
|
60
60
|
"files": [
|
|
@@ -4,183 +4,14 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
Bytes,
|
|
9
|
-
CRYPTO_AUTH_TAG_LENGTH,
|
|
10
|
-
CRYPTO_EC_CURVE,
|
|
11
|
-
CRYPTO_EC_KEY_BYTES,
|
|
12
|
-
CRYPTO_ENCRYPT_ALGORITHM,
|
|
13
|
-
CRYPTO_HASH_ALGORITHM,
|
|
14
|
-
CRYPTO_SYMMETRIC_KEY_LENGTH,
|
|
15
|
-
Crypto,
|
|
16
|
-
CryptoDecryptError,
|
|
17
|
-
CryptoDsaEncoding,
|
|
18
|
-
CryptoVerifyError,
|
|
19
|
-
PrivateKey,
|
|
20
|
-
PublicKey,
|
|
21
|
-
asError,
|
|
22
|
-
} from "#general";
|
|
7
|
+
import { NodeJsStyleCrypto } from "#general";
|
|
23
8
|
import * as crypto from "node:crypto";
|
|
24
9
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
});
|
|
32
|
-
if (aad !== undefined) {
|
|
33
|
-
cipher.setAAD(Bytes.of(aad), { plaintextLength: data.byteLength });
|
|
34
|
-
}
|
|
35
|
-
const encrypted = cipher.update(Bytes.of(data));
|
|
36
|
-
cipher.final();
|
|
37
|
-
return Bytes.concat(Bytes.of(encrypted), Bytes.of(cipher.getAuthTag()));
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
decrypt(key: Bytes, encrypted: Bytes, nonce: Bytes, aad?: Bytes): Bytes {
|
|
41
|
-
const cipher = crypto.createDecipheriv(CRYPTO_ENCRYPT_ALGORITHM, Bytes.of(key), Bytes.of(nonce), {
|
|
42
|
-
authTagLength: CRYPTO_AUTH_TAG_LENGTH,
|
|
43
|
-
});
|
|
44
|
-
const data = Bytes.of(encrypted);
|
|
45
|
-
const plaintextLength = data.length - CRYPTO_AUTH_TAG_LENGTH;
|
|
46
|
-
if (aad !== undefined) {
|
|
47
|
-
cipher.setAAD(Bytes.of(aad), { plaintextLength });
|
|
48
|
-
}
|
|
49
|
-
cipher.setAuthTag(data.slice(plaintextLength));
|
|
50
|
-
const result = cipher.update(data.slice(0, plaintextLength));
|
|
51
|
-
try {
|
|
52
|
-
cipher.final();
|
|
53
|
-
} catch (e) {
|
|
54
|
-
throw new CryptoDecryptError(`${CRYPTO_ENCRYPT_ALGORITHM} decryption failed: ${asError(e).message}`);
|
|
55
|
-
}
|
|
56
|
-
return new Uint8Array(result);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
randomBytes(length: number): Bytes {
|
|
60
|
-
return new Uint8Array(crypto.randomBytes(length));
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
ecdhGeneratePublicKey(): { publicKey: Bytes; ecdh: any } {
|
|
64
|
-
const ecdh = crypto.createECDH(CRYPTO_EC_CURVE);
|
|
65
|
-
ecdh.generateKeys();
|
|
66
|
-
return { publicKey: new Uint8Array(ecdh.getPublicKey()), ecdh: ecdh };
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
ecdhGeneratePublicKeyAndSecret(peerPublicKey: Bytes): {
|
|
70
|
-
publicKey: Bytes;
|
|
71
|
-
sharedSecret: Bytes;
|
|
72
|
-
} {
|
|
73
|
-
const ecdh = crypto.createECDH(CRYPTO_EC_CURVE);
|
|
74
|
-
ecdh.generateKeys();
|
|
75
|
-
return {
|
|
76
|
-
publicKey: new Uint8Array(ecdh.getPublicKey()),
|
|
77
|
-
sharedSecret: new Uint8Array(ecdh.computeSecret(Bytes.of(peerPublicKey))),
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
computeSha256(data: Bytes | Bytes[]): Bytes {
|
|
82
|
-
const hasher = crypto.createHash(CRYPTO_HASH_ALGORITHM);
|
|
83
|
-
if (Array.isArray(data)) {
|
|
84
|
-
data.forEach(chunk => hasher.update(Bytes.of(chunk)));
|
|
85
|
-
} else {
|
|
86
|
-
hasher.update(Bytes.of(data));
|
|
87
|
-
}
|
|
88
|
-
return new Uint8Array(hasher.digest());
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
createPbkdf2Key(secret: Bytes, salt: Bytes, iteration: number, keyLength: number): Promise<Bytes> {
|
|
92
|
-
return new Promise<Bytes>((resolver, rejecter) => {
|
|
93
|
-
crypto.pbkdf2(
|
|
94
|
-
Bytes.of(secret),
|
|
95
|
-
Bytes.of(salt),
|
|
96
|
-
iteration,
|
|
97
|
-
keyLength,
|
|
98
|
-
CRYPTO_HASH_ALGORITHM,
|
|
99
|
-
(error, key) => {
|
|
100
|
-
if (error !== null) rejecter(error);
|
|
101
|
-
resolver(new Uint8Array(key));
|
|
102
|
-
},
|
|
103
|
-
);
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
createHkdfKey(
|
|
108
|
-
secret: Bytes,
|
|
109
|
-
salt: Bytes,
|
|
110
|
-
info: Bytes,
|
|
111
|
-
length: number = CRYPTO_SYMMETRIC_KEY_LENGTH,
|
|
112
|
-
): Promise<Bytes> {
|
|
113
|
-
return new Promise<Bytes>((resolver, rejecter) => {
|
|
114
|
-
crypto.hkdf(
|
|
115
|
-
CRYPTO_HASH_ALGORITHM,
|
|
116
|
-
Bytes.of(secret),
|
|
117
|
-
Bytes.of(salt),
|
|
118
|
-
Bytes.of(info),
|
|
119
|
-
length,
|
|
120
|
-
(error, key) => {
|
|
121
|
-
if (error !== null) rejecter(error);
|
|
122
|
-
resolver(new Uint8Array(key));
|
|
123
|
-
},
|
|
124
|
-
);
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
signHmac(key: Bytes, data: Bytes): Bytes {
|
|
129
|
-
const hmac = crypto.createHmac(CRYPTO_HASH_ALGORITHM, Bytes.of(key));
|
|
130
|
-
hmac.update(Bytes.of(data));
|
|
131
|
-
return new Uint8Array(hmac.digest());
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
signEcdsa(privateKey: JsonWebKey, data: Bytes | Bytes[], dsaEncoding: CryptoDsaEncoding = "ieee-p1363"): Bytes {
|
|
135
|
-
const signer = crypto.createSign(CRYPTO_HASH_ALGORITHM);
|
|
136
|
-
if (Array.isArray(data)) {
|
|
137
|
-
data.forEach(chunk => signer.update(Bytes.of(chunk)));
|
|
138
|
-
} else {
|
|
139
|
-
signer.update(Bytes.of(data));
|
|
140
|
-
}
|
|
141
|
-
return new Uint8Array(
|
|
142
|
-
signer.sign({
|
|
143
|
-
key: privateKey as any,
|
|
144
|
-
format: "jwk",
|
|
145
|
-
type: "pkcs8",
|
|
146
|
-
dsaEncoding,
|
|
147
|
-
}),
|
|
148
|
-
);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
verifyEcdsa(publicKey: JsonWebKey, data: Bytes, signature: Bytes, dsaEncoding: CryptoDsaEncoding = "ieee-p1363") {
|
|
152
|
-
const verifier = crypto.createVerify(CRYPTO_HASH_ALGORITHM);
|
|
153
|
-
verifier.update(Bytes.of(data));
|
|
154
|
-
const success = verifier.verify(
|
|
155
|
-
{
|
|
156
|
-
key: publicKey as any,
|
|
157
|
-
format: "jwk",
|
|
158
|
-
type: "spki",
|
|
159
|
-
dsaEncoding,
|
|
160
|
-
},
|
|
161
|
-
Bytes.of(signature),
|
|
162
|
-
);
|
|
163
|
-
if (!success) throw new CryptoVerifyError("Signature verification failed");
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
createKeyPair() {
|
|
167
|
-
// Note that we this key may be used for DH or DSA but we use an ECDH to generate
|
|
168
|
-
const ecdh = crypto.createECDH(CRYPTO_EC_CURVE);
|
|
169
|
-
ecdh.generateKeys();
|
|
170
|
-
|
|
171
|
-
// The key exported from Node doesn't include most-significant bytes that are 0. This doesn't affect how we
|
|
172
|
-
// currently use keys but it's a little weird so 0 pad to avoid future confusion
|
|
173
|
-
const privateKey = new Uint8Array(CRYPTO_EC_KEY_BYTES);
|
|
174
|
-
const nodePrivateKey = ecdh.getPrivateKey();
|
|
175
|
-
privateKey.set(nodePrivateKey, CRYPTO_EC_KEY_BYTES - nodePrivateKey.length);
|
|
176
|
-
|
|
177
|
-
return PrivateKey(privateKey, { publicKey: Bytes.of(ecdh.getPublicKey()) });
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
generateDhSecret(key: PrivateKey, peerKey: PublicKey): Bytes {
|
|
181
|
-
const ecdh = crypto.createECDH(CRYPTO_EC_CURVE);
|
|
182
|
-
ecdh.setPrivateKey(Bytes.of(key.privateBits));
|
|
183
|
-
|
|
184
|
-
return Bytes.of(ecdh.computeSecret(Bytes.of(peerKey.publicBits)));
|
|
10
|
+
/**
|
|
11
|
+
* Node.js-based crypto implementation.
|
|
12
|
+
*/
|
|
13
|
+
export class NodeJsCrypto extends NodeJsStyleCrypto {
|
|
14
|
+
constructor() {
|
|
15
|
+
super(crypto);
|
|
185
16
|
}
|
|
186
17
|
}
|