-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathvault.js
More file actions
76 lines (65 loc) · 1.81 KB
/
Copy pathvault.js
File metadata and controls
76 lines (65 loc) · 1.81 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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// vault.js - AES-GCM encryption helper for SecureWeb
const Vault = (() => {
const algo = {
name: "AES-GCM",
length: 256
};
async function generateKey() {
const key = await crypto.subtle.generateKey(algo, true, ["encrypt", "decrypt"]);
const jwk = await crypto.subtle.exportKey("jwk", key);
return jwk;
}
async function importKey(jwk) {
return crypto.subtle.importKey("jwk", jwk, algo, true, ["encrypt", "decrypt"]);
}
function strToBuf(str) {
return new TextEncoder().encode(str);
}
function bufToStr(buf) {
return new TextDecoder().decode(buf);
}
function bufToBase64(buf) {
const bytes = new Uint8Array(buf);
let bin = "";
for (let i = 0; i < bytes.length; i++) bin += String.fromCharCode(bytes[i]);
return btoa(bin);
}
function base64ToBuf(b64) {
const bin = atob(b64);
const buf = new Uint8Array(bin.length);
for (let i = 0; i < bin.length; i++) buf[i] = bin.charCodeAt(i);
return buf.buffer;
}
async function encrypt(jwk, plaintext) {
const key = await importKey(jwk);
const iv = crypto.getRandomValues(new Uint8Array(12));
const enc = await crypto.subtle.encrypt(
{ name: "AES-GCM", iv },
key,
strToBuf(plaintext)
);
return {
iv: bufToBase64(iv),
data: bufToBase64(enc)
};
}
async function decrypt(jwk, obj) {
const key = await importKey(jwk);
const iv = base64ToBuf(obj.iv);
const data = base64ToBuf(obj.data);
const dec = await crypto.subtle.decrypt(
{ name: "AES-GCM", iv: new Uint8Array(iv) },
key,
data
);
return bufToStr(dec);
}
return {
generateKey,
encrypt,
decrypt
};
})();
if (typeof window !== "undefined") {
window.Vault = Vault;
}