Skip to content

Commit 518851e

Browse files
committed
feat: better crypto tests
1 parent 669d6ab commit 518851e

File tree

4 files changed

+58
-104
lines changed

4 files changed

+58
-104
lines changed

src/common/crypto.spec.ts

+6-89
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import { DefaultLogger } from '.'
55
import { decrypt, deriveKeyPbkdf2, digest, encrypt, randomUint8Array } from './crypto'
6-
import { equalBinary, toHex } from './data/bin'
6+
import { equalBinary, fromBase64, toBase64 } from './data/bin'
77

88
const log = DefaultLogger('crypto.spec')
99

@@ -16,54 +16,15 @@ describe('crypto', () => {
1616
let id: Uint8Array | undefined
1717
while ((id = list.pop())) {
1818
// console.log(id)
19-
expect(equalBinary(id, new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0]))).toBe(
20-
false,
21-
)
19+
expect(equalBinary(id, new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0]))).toBe(false)
2220
expect(id?.length).toBe(8)
2321
expect(list).not.toContain(id)
2422
}
2523
})
2624

2725
it('should digest', async () => {
28-
expect(toHex(await digest('abc'))).toBe(
29-
'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad',
30-
)
31-
expect(await digest(new Uint8Array([1, 2, 3]))).toMatchInlineSnapshot(`
32-
Uint8Array [
33-
3,
34-
144,
35-
88,
36-
198,
37-
242,
38-
192,
39-
203,
40-
73,
41-
44,
42-
83,
43-
59,
44-
10,
45-
77,
46-
20,
47-
239,
48-
119,
49-
204,
50-
15,
51-
120,
52-
171,
53-
204,
54-
206,
55-
213,
56-
40,
57-
125,
58-
132,
59-
161,
60-
162,
61-
1,
62-
28,
63-
251,
64-
129,
65-
]
66-
`)
26+
expect(toBase64(await digest('abc'))).toBe('ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0=')
27+
expect(toBase64(await digest(new Uint8Array([1, 2, 3])))).toMatchInlineSnapshot(`"A5BYxvLAy0ksUzsKTRTvd8wPeKvMztUofYShogEc+4E="`)
6728
})
6829

6930
// it("should derive key", async () => {
@@ -92,56 +53,12 @@ Uint8Array [
9253
})
9354
const sample = new Uint8Array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
9455
const cipher = await encrypt(sample, key)
95-
// log("cipher", cipher)
56+
log('cipher', toBase64(cipher))
9657

9758
const bin = await decrypt(cipher, key)
9859
expect(equalBinary(sample, bin)).toBe(true)
9960

100-
const binFix = await decrypt(
101-
new Uint8Array([
102-
1,
103-
1,
104-
27,
105-
108,
106-
252,
107-
31,
108-
238,
109-
192,
110-
61,
111-
168,
112-
45,
113-
29,
114-
128,
115-
212,
116-
215,
117-
222,
118-
205,
119-
105,
120-
178,
121-
193,
122-
150,
123-
36,
124-
24,
125-
216,
126-
180,
127-
75,
128-
168,
129-
133,
130-
37,
131-
25,
132-
124,
133-
137,
134-
221,
135-
103,
136-
214,
137-
97,
138-
218,
139-
232,
140-
248,
141-
93,
142-
]),
143-
key,
144-
)
61+
const binFix = await decrypt(fromBase64('AQELynGCxvLXKwLM/oHjOaM4R6d7oAzxJpgpCZnKmWwhkwIDzpPMUQ=='), key)
14562
expect(binFix).toEqual(sample)
14663
})
14764

src/common/crypto.ts

+32
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,38 @@ export async function deriveKeyPbkdf2(
6666
)
6767
}
6868

69+
export async function deriveKeyPbkdf2CBC(
70+
secret: BinInput,
71+
opt: {
72+
iterations?: number
73+
salt?: BinInput
74+
} = {},
75+
): Promise<CryptoKey> {
76+
const secretBuffer = toUint8Array(secret)
77+
const keyMaterial = await crypto.subtle.importKey(
78+
'raw',
79+
secretBuffer,
80+
CRYPTO_DEFAULT_DERIVE_ALG,
81+
false,
82+
['deriveKey'],
83+
)
84+
return await crypto.subtle.deriveKey(
85+
{
86+
name: CRYPTO_DEFAULT_DERIVE_ALG,
87+
salt: opt.salt ? toUint8Array(opt.salt) : new Uint8Array(0),
88+
iterations: opt.iterations ?? CRYPTO_DEFAULT_DERIVE_ITERATIONS,
89+
hash: CRYPTO_DEFAULT_HASH_ALG,
90+
},
91+
keyMaterial,
92+
{
93+
name: CRYPTO_DEFAULT_ALG,
94+
length: 256,
95+
},
96+
true,
97+
['encrypt', 'decrypt'],
98+
)
99+
}
100+
69101
function getMagicId() {
70102
return new Uint8Array([1, 1])
71103
}

src/common/crypto/aes-sealed.spec.ts

+11-13
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import { beforeAll, describe, expect, it } from 'vitest'
2-
import { deriveKeyPbkdf2CBC } from '../crypto'
3-
import { fromBase64 } from '../data'
42
import { hxDecrypt, hxEncrypt } from './aes-sealed'
53

6-
describe('aES Encryption and Decryption', () => {
4+
describe('aes Encryption and Decryption', () => {
75
let key: CryptoKey
86

97
beforeAll(async () => {
@@ -45,14 +43,14 @@ describe('aES Encryption and Decryption', () => {
4543
await expect(hxDecrypt(encryptedData, differentKey)).rejects.toThrow()
4644
})
4745

48-
it('should decrypt a sample that was generated by Swift code', async () => {
49-
const key = await deriveKeyPbkdf2CBC(new Uint8Array([1, 2, 3]), {
50-
salt: new Uint8Array([1, 2, 3]),
51-
})
52-
// expect(toBase64(key)).toMatchInlineSnapshot()
53-
const sample = new Uint8Array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
54-
const encryptedData = fromBase64('br6sc+pnZaIXcV1fTygAs/UJlDZIIBY50i56MMGNampZTcSakt0=')
55-
const decryptedData = await hxDecrypt(encryptedData, key)
56-
expect(decryptedData).toMatchInlineSnapshot()
57-
})
46+
// it('should decrypt a sample that was generated by Swift code', async () => {
47+
// const key = await deriveKeyPbkdf2CBC(new Uint8Array([1, 2, 3]), {
48+
// salt: new Uint8Array([1, 2, 3]),
49+
// })
50+
// // expect(toBase64(key)).toMatchInlineSnapshot()
51+
// const sample = new Uint8Array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
52+
// const encryptedData = fromBase64('br6sc+pnZaIXcV1fTygAs/UJlDZIIBY50i56MMGNampZTcSakt0=')
53+
// const decryptedData = await hxDecrypt(encryptedData, key)
54+
// expect(decryptedData).toMatchInlineSnapshot()
55+
// })
5856
})

src/common/crypto/aes-sealed.ts

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,25 @@
1-
export async function hxEncrypt(data: Uint8Array, key: CryptoKey): Promise<Uint8Array> {
1+
export async function hxEncrypt(data: Uint8Array, key: CryptoKey, tag?: Uint8Array): Promise<Uint8Array> {
22
const iv = crypto.getRandomValues(new Uint8Array(12)) // AES-GCM requires a 12-byte IV
3+
if (!tag) {
4+
tag = crypto.getRandomValues(new Uint8Array(16))
5+
}
6+
37
const encrypted = await crypto.subtle.encrypt(
48
{
59
name: 'AES-GCM',
610
iv,
11+
tagLength: 128,
12+
additionalData: tag,
713
},
814
key,
915
data,
1016
)
1117

1218
const encryptedArray = new Uint8Array(encrypted)
13-
const combined = new Uint8Array(iv.length + encryptedArray.length)
19+
const combined = new Uint8Array(iv.length + encryptedArray.length + tag.length)
1420
combined.set(iv)
1521
combined.set(encryptedArray, iv.length)
22+
combined.set(tag, encryptedArray.length + iv.length)
1623
return combined
1724
}
1825

0 commit comments

Comments
 (0)