forked from mozilla/send
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkeychain.js
More file actions
53 lines (50 loc) · 1.23 KB
/
keychain.js
File metadata and controls
53 lines (50 loc) · 1.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
const { Crypto } = require('@peculiar/webcrypto');
const crypto = new Crypto();
const encoder = new TextEncoder();
const decoder = new TextDecoder();
module.exports = class Keychain {
constructor(secretKeyB64) {
if (secretKeyB64) {
this.rawSecret = new Uint8Array(Buffer.from(secretKeyB64, 'base64'));
} else {
throw new Error('key is required');
}
this.secretKeyPromise = crypto.subtle.importKey(
'raw',
this.rawSecret,
'HKDF',
false,
['deriveKey']
);
this.metaKeyPromise = this.secretKeyPromise.then(function(secretKey) {
return crypto.subtle.deriveKey(
{
name: 'HKDF',
salt: new Uint8Array(),
info: encoder.encode('metadata'),
hash: 'SHA-256'
},
secretKey,
{
name: 'AES-GCM',
length: 128
},
false,
['decrypt']
);
});
}
async decryptMetadata(ciphertext) {
const metaKey = await this.metaKeyPromise;
const plaintext = await crypto.subtle.decrypt(
{
name: 'AES-GCM',
iv: new Uint8Array(12),
tagLength: 128
},
metaKey,
ciphertext
);
return JSON.parse(decoder.decode(plaintext));
}
};