Skip to content

Commit d09e57e

Browse files
committed
aes: improve compatibility between browser and nodejs
1 parent 92f71f8 commit d09e57e

File tree

2 files changed

+70
-29
lines changed

2 files changed

+70
-29
lines changed

src/aes.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ async function getBrowserKey(
4141
true,
4242
["encrypt", "decrypt"]
4343
);
44-
return [wKey, { name: `aes-${keyMode}`, iv, counter: iv, length: 64 }];
44+
// node.js uses whole 128 bit as a counter, without nonce, instead of 64 bit
45+
// recommended by NIST SP800-38A
46+
return [wKey, { name: `aes-${keyMode}`, iv, counter: iv, length: 128 }];
4547
}
4648

4749
export async function encrypt(

test/test-vectors/aes.ts

Lines changed: 67 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,98 +7,89 @@ const TEST_VECTORS = [
77
mode: "aes-128-ctr",
88
key: "2b7e151628aed2a6abf7158809cf4f3c",
99
iv: "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
10-
msg:
11-
"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
10+
msg: "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
1211
cypherText:
1312
"874d6191b620e3261bef6864990db6ce9806f66b7970fdff8617187bb9fffdff5ae4df3edbd5d35e5b4f09020db03eab1e031dda2fbe03d1792170a0f3009cee",
14-
pkcs7PaddingEnabled: false
13+
pkcs7PaddingEnabled: false,
1514
},
1615
// CTR uses no padding, so we test that here
1716
{
1817
mode: "aes-128-ctr",
1918
key: "2b7e151628aed2a6abf7158809cf4f3c",
2019
iv: "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
21-
msg:
22-
"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
20+
msg: "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
2321
cypherText:
2422
"874d6191b620e3261bef6864990db6ce9806f66b7970fdff8617187bb9fffdff5ae4df3edbd5d35e5b4f09020db03eab1e031dda2fbe03d1792170a0f3009cee",
25-
pkcs7PaddingEnabled: true
23+
pkcs7PaddingEnabled: true,
2624
},
2725
// Same as the previous one, but with default params
2826
{
2927
mode: undefined,
3028
key: "2b7e151628aed2a6abf7158809cf4f3c",
3129
iv: "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
32-
msg:
33-
"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
30+
msg: "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
3431
cypherText:
3532
"874d6191b620e3261bef6864990db6ce9806f66b7970fdff8617187bb9fffdff5ae4df3edbd5d35e5b4f09020db03eab1e031dda2fbe03d1792170a0f3009cee",
36-
pkcs7PaddingEnabled: undefined
33+
pkcs7PaddingEnabled: undefined,
3734
},
3835
// CBC uses padding, but the NIST test vectors don't
3936
{
4037
mode: "aes-128-cbc",
4138
key: "2b7e151628aed2a6abf7158809cf4f3c",
4239
iv: "000102030405060708090a0b0c0d0e0f",
43-
msg:
44-
"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
40+
msg: "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
4541
cypherText:
4642
"7649abac8119b246cee98e9b12e9197d5086cb9b507219ee95db113a917678b273bed6b8e3c1743b7116e69e222295163ff1caa1681fac09120eca307586e1a7",
47-
pkcs7PaddingEnabled: false
43+
pkcs7PaddingEnabled: false,
4844
},
4945
// We test that the padding is in fact PKCS#7 by first entrypting with its
5046
// corresponding padding adding manually, and then with automatic padding
5147
{
5248
mode: "aes-128-cbc",
5349
key: "2b7e151628aed2a6abf7158809cf4f3c",
5450
iv: "000102030405060708090a0b0c0d0e0f",
55-
msg:
56-
"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c371010101010101010101010101010101010",
51+
msg: "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c371010101010101010101010101010101010",
5752
cypherText:
5853
"7649abac8119b246cee98e9b12e9197d5086cb9b507219ee95db113a917678b273bed6b8e3c1743b7116e69e222295163ff1caa1681fac09120eca307586e1a78cb82807230e1321d3fae00d18cc2012",
59-
pkcs7PaddingEnabled: false
54+
pkcs7PaddingEnabled: false,
6055
},
6156
{
6257
mode: "aes-128-cbc",
6358
key: "2b7e151628aed2a6abf7158809cf4f3c",
6459
iv: "000102030405060708090a0b0c0d0e0f",
65-
msg:
66-
"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
60+
msg: "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
6761
cypherText:
6862
"7649abac8119b246cee98e9b12e9197d5086cb9b507219ee95db113a917678b273bed6b8e3c1743b7116e69e222295163ff1caa1681fac09120eca307586e1a78cb82807230e1321d3fae00d18cc2012",
69-
pkcs7PaddingEnabled: true
63+
pkcs7PaddingEnabled: true,
7064
},
7165
// Same applies for aes-256-cbc
7266
{
7367
mode: "aes-256-cbc",
7468
key: "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
7569
iv: "000102030405060708090a0b0c0d0e0f",
76-
msg:
77-
"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
70+
msg: "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
7871
cypherText:
7972
"f58c4c04d6e5f1ba779eabfb5f7bfbd69cfc4e967edb808d679f777bc6702c7d39f23369a9d9bacfa530e26304231461b2eb05e2c39be9fcda6c19078c6a9d1b",
80-
pkcs7PaddingEnabled: false
73+
pkcs7PaddingEnabled: false,
8174
},
8275
{
8376
mode: "aes-256-cbc",
8477
key: "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
8578
iv: "000102030405060708090a0b0c0d0e0f",
86-
msg:
87-
"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c371010101010101010101010101010101010",
79+
msg: "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c371010101010101010101010101010101010",
8880
cypherText:
8981
"f58c4c04d6e5f1ba779eabfb5f7bfbd69cfc4e967edb808d679f777bc6702c7d39f23369a9d9bacfa530e26304231461b2eb05e2c39be9fcda6c19078c6a9d1b3f461796d6b0d6b2e0c2a72b4d80e644",
90-
pkcs7PaddingEnabled: false
82+
pkcs7PaddingEnabled: false,
9183
},
9284
{
9385
mode: "aes-256-cbc",
9486
key: "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
9587
iv: "000102030405060708090a0b0c0d0e0f",
96-
msg:
97-
"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
88+
msg: "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
9889
cypherText:
9990
"f58c4c04d6e5f1ba779eabfb5f7bfbd69cfc4e967edb808d679f777bc6702c7d39f23369a9d9bacfa530e26304231461b2eb05e2c39be9fcda6c19078c6a9d1b3f461796d6b0d6b2e0c2a72b4d80e644",
100-
pkcs7PaddingEnabled: true
101-
}
91+
pkcs7PaddingEnabled: true,
92+
},
10293
];
10394

10495
describe("aes", () => {
@@ -151,4 +142,52 @@ describe("aes", () => {
151142
)
152143
);
153144
});
145+
146+
it("aes-ctr bug (browser/node result mismatch)", async () => {
147+
// NOTE: full 0xff iv causes difference on counter overflow in CTR mode
148+
const iv = "ffffffffffffffffffffffffffffffff";
149+
const vectors = [
150+
{
151+
msg: "efca4cdd31923b50f4214af5d2ae10e7ac45a5019e9431cc195482d707485378",
152+
key: "ccc0b35ea59c51a1e45af00502966237",
153+
iv,
154+
mode: "aes-128-ctr",
155+
result:
156+
"15e356c67d266d3ca85cff4f6d92d11720aae32cdd28d5d9885836dacb1d213b",
157+
},
158+
{
159+
msg: "efca4cdd31923b50f4214af5d2ae10e7ac45a5019e9431cc195482d707485378",
160+
key: "ccc0b35ea59c51a1e45af00502966237ccc0b35ea59c51a1e45af00502966237",
161+
iv,
162+
mode: "aes-256-ctr",
163+
result:
164+
"010bb6dc10ea201bf2d586de4741309373c07b6ddf30ad8502adf4dd0bda2d23",
165+
},
166+
{
167+
msg: "efca4cdd31923b50f4214af5d2ae10e7ac45a5019e9431cc195482d707485378efca4cdd31923b50f4214af5d2ae10e7ac45a5019e9431cc195482d707485378",
168+
key: "ccc0b35ea59c51a1e45af00502966237",
169+
iv,
170+
mode: "aes-128-ctr",
171+
result:
172+
"15e356c67d266d3ca85cff4f6d92d11720aae32cdd28d5d9885836dacb1d213b55f347e68f72acf46234d495f579fb45f9dcfc7dc688a9174f566d137ffc626c",
173+
},
174+
{
175+
msg: "efca4cdd31923b50f4214af5d2ae10e7ac45a5019e9431cc195482d707485378efca4cdd31923b50f4214af5d2ae10e7ac45a5019e9431cc195482d707485378",
176+
key: "ccc0b35ea59c51a1e45af00502966237ccc0b35ea59c51a1e45af00502966237",
177+
iv,
178+
mode: "aes-256-ctr",
179+
result:
180+
"010bb6dc10ea201bf2d586de4741309373c07b6ddf30ad8502adf4dd0bda2d23c436b35e5dfa0a0088dcb6ae7328f1ec66212099222ee1c18983b58513cf5f4c",
181+
},
182+
];
183+
for (const v of vectors) {
184+
const msg = hexToBytes(v.msg);
185+
const key = hexToBytes(v.key);
186+
const iv = hexToBytes(v.iv);
187+
const res = await encrypt(msg, key, iv, v.mode);
188+
deepStrictEqual(toHex(res), v.result);
189+
const clearText = await decrypt(res, key, iv, v.mode);
190+
deepStrictEqual(clearText, msg);
191+
}
192+
});
154193
});

0 commit comments

Comments
 (0)