-
Notifications
You must be signed in to change notification settings - Fork 1.8k
/
jwk.js
98 lines (87 loc) · 2.8 KB
/
jwk.js
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
94
95
96
97
98
(() => {
const jwkEcKey = {
"crv": "P-384",
"d": "wouCtU7Nw4E8_7n5C1-xBjB4xqSb_liZhYMsy8MGgxUny6Q8NCoH9xSiviwLFfK_",
"ext": true,
"key_ops": ["sign"],
"kty": "EC",
"x": "SzrRXmyI8VWFJg1dPUNbFcc9jZvjZEfH7ulKI1UkXAltd7RGWrcfFxqyGPcwu6AQ",
"y": "hHUag3OvDzEr0uUQND4PXHQTXP5IDGdYhJhL-WLKjnGjQAw0rNGy5V29-aV-yseW"
};
/*
The unwrapped signing key.
*/
let signingKey;
const signButton = document.querySelector(".jwk .sign-button");
/*
Import a JSON Web Key format EC private key, to use for ECDSA signing.
Takes a string containing the JSON Web Key, and returns a Promise
that will resolve to a CryptoKey representing the private key.
*/
function importPrivateKey(jwk) {
return window.crypto.subtle.importKey(
"jwk",
jwk,
{
name: "ECDSA",
namedCurve: "P-384"
},
true,
["sign"]
);
}
/*
Fetch the contents of the "message" textbox, and encode it
in a form we can use for the sign operation.
*/
function getMessageEncoding() {
const messageBox = document.querySelector("#jwk-message");
const message = messageBox.value;
const enc = new TextEncoder();
return enc.encode(message);
}
/*
Get the encoded message-to-sign, sign it and display a representation
of the first part of it in the "signature" element.
*/
async function signMessage() {
const encoded = getMessageEncoding();
const signature = await window.crypto.subtle.sign(
{
name: "ECDSA",
hash: "SHA-512"
},
signingKey,
encoded
);
const signatureValue = document.querySelector(".jwk .signature-value");
signatureValue.classList.add('fade-in');
signatureValue.addEventListener('animationend', () => {
signatureValue.classList.remove('fade-in');
}, { once: true });
const buffer = new Uint8Array(signature, 0, 5);
signatureValue.textContent = `${buffer}...[${signature.byteLength} bytes total]`;
}
/*
Show and enable the sign button.
*/
function enableSignButton() {
signButton.classList.add('fade-in');
signButton.addEventListener('animationend', () => {
signButton.classList.remove('fade-in');
}, { once: true });
signButton.removeAttribute("disabled");
signButton.classList.remove("hidden");
}
/*
When the user clicks "Import Key"
- import the key
- enable the "Sign" button
*/
const importKeyButton = document.querySelector(".jwk .import-key-button");
importKeyButton.addEventListener("click", async () => {
signingKey = await importPrivateKey(jwkEcKey);
enableSignButton();
});
signButton.addEventListener("click", signMessage);
})();