-
Notifications
You must be signed in to change notification settings - Fork 0
/
SelfDecryptingLib.ts
84 lines (69 loc) · 2.34 KB
/
SelfDecryptingLib.ts
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
export function bufferToUint8Array(buffer : Buffer) : Uint8Array {
const len = buffer.length;
const bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) {
bytes[i] = buffer[i];
}
return bytes;
}
// Node.js and browser have different environments and
// different ways of converting between strings and binary data.
export function base64ToUint8Array(base64 : string) : Uint8Array{
if (typeof Buffer !== 'undefined') {
// Node.js environment for testing.
return bufferToUint8Array(Buffer.from(base64, 'base64'));
} else if (typeof atob !== 'undefined') {
// Browser environment
let binaryString = atob(base64);
const len = binaryString.length;
const bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes;
} else {
throw new Error('No suitable base64 decoding method found');
}
}
/* Compiled version of this function AND ALL HELPER FUNCTIONS
should be in SelfExtractingTemplate.html */
export async function decryptString(crypto, subtle, password: string, base64EncodedSalt: string, base64EncodedIv: string, base64EncodedEncryptedFile: string) : Promise<Uint8Array|null>{
let salt : Uint8Array = base64ToUint8Array(base64EncodedSalt)
// Derive a key from the password
const key = await subtle.importKey(
'raw',
new TextEncoder().encode(password),
{ name: 'PBKDF2' },
false,
['deriveBits', 'deriveKey']
);
const aesKey = await subtle.deriveKey(
{
name: 'PBKDF2',
salt: salt.buffer,
iterations: 600000,
hash: 'SHA-256'
},
key,
{ name: 'AES-GCM', length: 256 },
true,
['encrypt', 'decrypt']
);
// Decrypt the file
const iv : Uint8Array = base64ToUint8Array(base64EncodedIv)
const encryptedFile : Uint8Array = base64ToUint8Array(base64EncodedEncryptedFile)
try {
const decryptedFile : ArrayBuffer = await subtle.decrypt(
{
name: 'AES-GCM',
iv: iv.buffer
},
aesKey,
encryptedFile
);
return new Uint8Array(decryptedFile);
} catch (e) {
console.error(e);
return null;
}
}