Skip to content

Commit 7f7bc65

Browse files
author
Will Bamberg
committed
Show error message for unwrap failure; make new button appearance more obvious
1 parent 8a10498 commit 7f7bc65

File tree

4 files changed

+93
-24
lines changed

4 files changed

+93
-24
lines changed

web-crypto/unwrap-key/index.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ <h1>Web Crypto: unwrapKey</h1>
1616
<li>Raw/AES-GCM/AES-KW: unwrap an AES-GCM encryption key, that was encrypted using AES-KW and exported in "raw" format.</li>
1717
<li>PKCS #8/RSA-PSS/AES-GCM: unwrap an RSA-PSS signing key, that was encrypted using AES-GCM and exported in "pkcs8" format.</li>
1818
</ul>
19-
<p>Both examples have the same structure: you get a message and two buttons, one labeled "Unwrap Key" and the other labeled either "Sign" or "Encrypt", depending on the type of key we are unwrapping. The "Sign"/"Encrypt" button is disabled initially.</p>
19+
<p>Both examples have the same structure: you get a message and a button labeled "Unwrap Key".</p>
2020
<p>If you click "Unwrap Key" then the example unwraps its particular key. First it will ask for a password: the password you must enter is <strong>correct horse battery staple</strong>. It uses the password to derive the key that was used to encrypt the wrapped key. It then unwraps the wrapped key. If you get the password wrong, unwrapping will fail.</p>
21-
<p>If unwrapping was successful, the "Sign"/"Encrypt" button is then enabled, and you can click it to use the unwrapped key to perform the appropriate operation and display the result.</p>
21+
<p>If unwrapping was successful, a new button is displayed, that enables you to use the unwrapped key. For "raw/AES-GCM" the new button is labeled "Encrypt", and for "pkcs8/RSA-PSS" it's labeled "Sign". You can click the new button to use the unwrapped key to perform the appropriate operation and display the result.</p>
2222
</section>
2323

2424
<section class="examples">
@@ -33,7 +33,7 @@ <h2 class="unwrap-key-heading">Raw/AES-GCM/AES-KW</h2>
3333
</div>
3434
<div class="ciphertext">Ciphertext:<span class="ciphertext-value"></span></div>
3535
<input class="unwrap-key-button" type="button" value="Unwrap Key">
36-
<input class="encrypt-button" type="button" value="Encrypt" disabled>
36+
<input class="encrypt-button hidden" type="button" value="Encrypt" disabled>
3737
</section>
3838
</section>
3939

@@ -47,7 +47,7 @@ <h2 class="unwrap-key-heading">PKCS #8/RSA-PSS/AES-GCM</h2>
4747
</div>
4848
<div class="signature">Signature:<span class="signature-value"></span></div>
4949
<input class="unwrap-key-button" type="button" value="Unwrap Key">
50-
<input class="sign-button" type="button" value="Sign" disabled>
50+
<input class="sign-button hidden" type="button" value="Sign" disabled>
5151
</section>
5252
</section>
5353

web-crypto/unwrap-key/pkcs8.js

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,13 @@
7979
40,148,187,39,234,96,151,16,158,114,113,109,164,47,108,94,148,35,232,221,
8080
33,110,126,170,25,234,45,165,180,210,193,120,247,155,127];
8181

82+
/*
83+
The unwrapped signing key.
84+
*/
85+
let signingKey;
86+
87+
const signButton = document.querySelector(".pkcs8 .sign-button");
88+
8289
/*
8390
Convert an array of byte values to an ArrayBuffer.
8491
*/
@@ -176,14 +183,14 @@
176183
Get the encoded message-to-sign, sign it and display a representation
177184
of the first part of it in the "signature" element.
178185
*/
179-
async function signMessage(privateKey) {
186+
async function signMessage() {
180187
const encoded = getMessageEncoding();
181188
const signature = await window.crypto.subtle.sign(
182189
{
183190
name: "RSA-PSS",
184191
saltLength: 32,
185192
},
186-
privateKey,
193+
signingKey,
187194
encoded
188195
);
189196

@@ -196,20 +203,43 @@
196203
signatureValue.textContent = `${buffer}...[${signature.byteLength} bytes total]`;
197204
}
198205

206+
/*
207+
Hide and disable the sign button if key unwrapping failed.
208+
*/
209+
function resetSignButton() {
210+
signButton.setAttribute("disabled", true);
211+
signButton.classList.add("hidden");
212+
}
213+
214+
/*
215+
Show and enable the sign button if key unwrapping succeeded.
216+
*/
217+
function enableSignButton() {
218+
signButton.classList.add('fade-in');
219+
signButton.addEventListener('animationend', () => {
220+
signButton.classList.remove('fade-in');
221+
});
222+
signButton.removeAttribute("disabled");
223+
signButton.classList.remove("hidden");
224+
}
225+
199226
/*
200227
When the user clicks "Unwrap Key"
201228
- unwrap the key
202-
- enable the "Sign" button
203-
- add a listener to "Sign" that uses the key.
229+
- if unwrapping succeeded, enable the "Sign" button
204230
*/
205231
const unwrapKeyButton = document.querySelector(".pkcs8 .unwrap-key-button");
206232
unwrapKeyButton.addEventListener("click", async () => {
207-
const privateKey = await unwrapPrivateKey(wrappedKeyBytes);
208-
const signButton = document.querySelector(".pkcs8 .sign-button");
209-
signButton.removeAttribute("disabled");
210-
signButton.addEventListener("click", () => {
211-
signMessage(privateKey);
212-
});
233+
try {
234+
signingKey = await unwrapPrivateKey(wrappedKeyBytes);
235+
enableSignButton();
236+
}
237+
catch(e) {
238+
resetSignButton();
239+
alert("Incorrect password");
240+
}
213241
});
214242

243+
signButton.addEventListener("click", signMessage);
244+
215245
})();

web-crypto/unwrap-key/raw.js

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@
1515
224,39,199,235,239,60,212,169,100,23,61,54,244,197,160,80,109,230,207,
1616
225,57,197,175,71,80,209];
1717

18+
/*
19+
The unwrapped secret key.
20+
*/
21+
let secretKey;
22+
23+
const encryptButton = document.querySelector(".raw .encrypt-button");
24+
1825
/*
1926
Convert an array of byte values to an ArrayBuffer.
2027
*/
@@ -103,7 +110,7 @@
103110
Get the encoded message, encrypt it and display a representation
104111
of the ciphertext in the "Ciphertext" element.
105112
*/
106-
async function encryptMessage(key) {
113+
async function encryptMessage() {
107114
const encoded = getMessageEncoding();
108115
// iv will be needed for decryption
109116
const iv = window.crypto.getRandomValues(new Uint8Array(12));
@@ -112,7 +119,7 @@
112119
name: "AES-GCM",
113120
iv: iv
114121
},
115-
key,
122+
secretKey,
116123
encoded
117124
);
118125

@@ -125,20 +132,43 @@
125132
ciphertextValue.textContent = `${buffer}...[${ciphertext.byteLength} bytes total]`;
126133
}
127134

135+
/*
136+
Hide and disable the encrypt button if key unwrapping failed.
137+
*/
138+
function resetEncryptButton() {
139+
encryptButton.setAttribute("disabled", true);
140+
encryptButton.classList.add("hidden");
141+
}
142+
143+
/*
144+
Show and enable the encrypt button if key unwrapping succeeded.
145+
*/
146+
function enableEncryptButton() {
147+
encryptButton.classList.add('fade-in');
148+
encryptButton.addEventListener('animationend', () => {
149+
encryptButton.classList.remove('fade-in');
150+
});
151+
encryptButton.removeAttribute("disabled");
152+
encryptButton.classList.remove("hidden");
153+
}
154+
128155
/*
129156
When the user clicks "Unwrap Key"
130157
- unwrap the key
131-
- enable the "Encrypt" button
132-
- add a listener to "Encrypt" that uses the key.
158+
- if unwrapping succeeded, enable the "Encrypt" button
133159
*/
134160
const unwrapKeyButton = document.querySelector(".raw .unwrap-key-button");
135161
unwrapKeyButton.addEventListener("click", async () => {
136-
const secretKey = await unwrapSecretKey(wrappedKeyBytes);
137-
const encryptButton = document.querySelector(".raw .encrypt-button");
138-
encryptButton.removeAttribute("disabled");
139-
encryptButton.addEventListener("click", () => {
140-
encryptMessage(secretKey);
141-
});
162+
try {
163+
secretKey = await unwrapSecretKey(wrappedKeyBytes);
164+
enableEncryptButton();
165+
}
166+
catch(e) {
167+
resetEncryptButton();
168+
alert("Incorrect password");
169+
}
142170
});
143171

172+
encryptButton.addEventListener("click", encryptMessage);
173+
144174
})();

web-crypto/unwrap-key/style.css

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,15 @@ h1 {
3939
font-family: monospace;
4040
}
4141

42+
.sign-button, .encrypt-button {
43+
background-color: green;
44+
color: white;
45+
}
46+
47+
.hidden {
48+
display: none;
49+
}
50+
4251
/* Whole page grid */
4352
main {
4453
display: grid;

0 commit comments

Comments
 (0)