Reputation: 16802
My code:
/*
Fetch the contents of the "message" textbox, and encode it
in a form we can use for the sign operation.
*/
function getMessageEncoding() {
const messageBox = 'hello world!';
let message = messageBox.value;
let enc = new TextEncoder();
return enc.encode(message);
}
async function main() {
let encoded = getMessageEncoding();
window.crypto.subtle.sign(
{
name: "ECDSA",
hash: { name: "SHA-384" },
},
{"alg":"ES256","crv":"P-256","d":"KRiXxoIFHmBQJdoCsqB8Bc9_f2Z-QCdRgoydMKdoL04","ext":true,"key_ops":["sign"],"kty":"EC","x":"FKwqyGd4i2NAl8RUXCCBRCAIbcpeGyfyXwgA_AWHb8Y","y":"njxhw5O6zGVkBlcPDKYj0E-6VO1giHTUkJWBhgKNqd8"},
encoded,
).then(signature => {
console.log(signature);
alert('test');
});
alert(signature);
}
main();
(the private key is a dummy private key and not a production one)
When I run it it doesn't do anything. I'd expect it to put the signature into the JS console?
Here it is on JS Fiddle:
https://jsfiddle.net/pwuersfL/1/
Any ideas?
Upvotes: 0
Views: 145
Reputation: 49331
In the posted code the key import with importKey()
is missing. importKey()
converts the JWK into a CryptoKey
which can be processed by sign()
.
In the following code the missing import is added (plus verifying):
function getMessageEncoding() {
//const messageBox = 'hello world!';
//let message = messageBox.value;
let message = 'hello world!'; // for testing
let enc = new TextEncoder();
return enc.encode(message);
}
async function main() {
// sign
let encoded = getMessageEncoding();
let jwk = {"alg":"ES256","crv":"P-256","d":"KRiXxoIFHmBQJdoCsqB8Bc9_f2Z-QCdRgoydMKdoL04","ext":true,"key_ops":["sign"],"kty":"EC","x":"FKwqyGd4i2NAl8RUXCCBRCAIbcpeGyfyXwgA_AWHb8Y","y":"njxhw5O6zGVkBlcPDKYj0E-6VO1giHTUkJWBhgKNqd8"};
let key = await window.crypto.subtle.importKey("jwk", jwk, {name: "ECDSA", namedCurve: "P-256"},true,["sign"]); // Fix: import the key
let signature = await window.crypto.subtle.sign(
{
name: "ECDSA",
hash: { name: "SHA-384" },
},
key,
encoded,
);
console.log(ab2hex(signature));
// verify
jwk = {"alg":"ES256","crv":"P-256","ext":true,"key_ops":["verify"],"kty":"EC","x":"FKwqyGd4i2NAl8RUXCCBRCAIbcpeGyfyXwgA_AWHb8Y","y":"njxhw5O6zGVkBlcPDKYj0E-6VO1giHTUkJWBhgKNqd8"};
key = await window.crypto.subtle.importKey("jwk", jwk, {name: "ECDSA", namedCurve: "P-256"},true,["verify"]);
let verified = await window.crypto.subtle.verify(
{
name: "ECDSA",
hash: { name: "SHA-384" },
},
key,
signature,
encoded,
);
console.log(verified);
}
// helper: hex encoding
function ab2hex(ab) {
return Array.prototype.map.call(new Uint8Array(ab), x => ('00' + x.toString(16)).slice(-2)).join('');
}
main();
The code produces for P-256 a 64 bytes signature in IEEE P1363 format (r|s), which can be successfully verified with the public key.
Upvotes: 1