-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Expand file tree
/
Copy pathraw.js
More file actions
85 lines (75 loc) · 2.05 KB
/
raw.js
File metadata and controls
85 lines (75 loc) · 2.05 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
77
78
79
80
81
82
83
84
85
(() => {
let salt;
/*
Get some key material to use as input to the deriveKey method.
The key material is a password supplied by the user.
*/
function getKeyMaterial() {
const password = window.prompt("Enter your password");
const enc = new TextEncoder();
return window.crypto.subtle.importKey(
"raw",
enc.encode(password),
{name: "PBKDF2"},
false,
["deriveBits", "deriveKey"]
);
}
/*
Given some key material and some random salt
derive an AES-KW key using PBKDF2.
*/
function getKey(keyMaterial, salt) {
return window.crypto.subtle.deriveKey(
{
"name": "PBKDF2",
salt: salt,
"iterations": 100000,
"hash": "SHA-256"
},
keyMaterial,
{ "name": "AES-KW", "length": 256},
true,
[ "wrapKey", "unwrapKey" ]
);
}
/*
Wrap the given key and write it into the "wrapped-key" space.
*/
async function wrapCryptoKey(keyToWrap) {
// get the key encryption key
const keyMaterial = await getKeyMaterial();
salt = window.crypto.getRandomValues(new Uint8Array(16));
const wrappingKey = await getKey(keyMaterial, salt);
const wrapped = await window.crypto.subtle.wrapKey(
"raw",
keyToWrap,
wrappingKey,
"AES-KW"
);
const wrappedKeyBuffer = new Uint8Array(wrapped);
const wrappedKeyOutput = document.querySelector(".wrapped-key");
wrappedKeyOutput.classList.add("fade-in");
wrappedKeyOutput.addEventListener("animationend", () => {
wrappedKeyOutput.classList.remove("fade-in");
}, { once: true });
wrappedKeyOutput.textContent = `[${wrappedKeyBuffer}]`;
}
/*
Generate an encrypt/decrypt secret key,
then set up an event listener on the "Wrap" button.
*/
window.crypto.subtle.generateKey(
{
name: "AES-GCM",
length: 256,
},
true,
["encrypt", "decrypt"]
).then((secretKey) => {
const wrapButton = document.querySelector(".raw");
wrapButton.addEventListener("click", () => {
wrapCryptoKey(secretKey);
});
});
})();