Repository navigation
Expand file tree
/
Copy pathpkcs8.js
More file actions
93 lines (83 loc) · 2.32 KB
/
Copy pathpkcs8.js
File metadata and controls
93 lines (83 loc) · 2.32 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
86
87
88
89
90
91
92
93
(() => {
let salt;
let iv;
/*
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-GCM key using PBKDF2.
*/
function getKey(keyMaterial, salt) {
return window.crypto.subtle.deriveKey(
{
"name": "PBKDF2",
salt: salt,
"iterations": 100000,
"hash": "SHA-256"
},
keyMaterial,
{ "name": "AES-GCM", "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);
iv = window.crypto.getRandomValues(new Uint8Array(12));
const wrapped = await window.crypto.subtle.wrapKey(
"pkcs8",
keyToWrap,
wrappingKey,
{
name: "AES-GCM",
iv
}
);
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 a sign/verify key pair,
then set up an event listener on the "Wrap" button.
*/
window.crypto.subtle.generateKey(
{
name: "RSA-PSS",
// Consider using a 4096-bit key for systems that require long-term security
modulusLength: 2048,
publicExponent: new Uint8Array([1, 0, 1]),
hash: "SHA-256",
},
true,
["sign", "verify"]
).then((keyPair) => {
const wrapButton = document.querySelector(".pkcs8");
wrapButton.addEventListener("click", () => {
wrapCryptoKey(keyPair.privateKey);
});
});
})();