I want to sign data, return the signature and the public key ( and "forget" the private key ). I want to use the Webcrypto API
Based on the docs I started with the following
const generateKeyPair = async function() {
return crypto.subtle.generateKey(
{
name: "ECDSA",
namedCurve: "P-384",
},
true,
["sign", "verify"]
);
}
const sign = async function(privateKey: CryptoKey, buffer: BufferSource) {
return crypto.subtle.sign(privateKey.algorithm, privateKey, buffer);
}
Based on my tests I think the function generateKeyPair
is fine. But when I try the sign
function like so
import { describe, it, expect } from "vitest";
import { generateKeyPair, sign } from "../../src";
describe("sign", () => {
it('returns a signature.', async () => {
const { privateKey } = await generateKeyPair();
const data = { foo: 'bar' };
const stringifiedData = JSON.stringify(data);
const buffer = Buffer.from(stringifiedData);
await expect(sign(privateKey, buffer)).resolves.toBeTruthy() // expect signature here
});
});
the test fails with the error
Error: promise rejected "TypeError [ERR_MISSING_OPTION]: algorithm.hash is required" instead of resolving
so I guess privateKey.algorithm
is lacking the internal hash
field. Am I using the wrong algorithm? I also tried to add "hash": "SHA-512"
to the options in generateKeyPair
.
I basically want to generate a key pair and use the private one for signing and the public one for reading.
Do you have any ideas?
You need to specify a name and hash for the signature algorithm to use. In the case of an ECDSA signature, you need to pass an EcdsaParams
object to the sign()
function:
const sign = async function(privateKey: CryptoKey, buffer: BufferSource) {
return crypto.subtle.sign({
name: 'ECDSA',
hash: 'SHA-512'
}, privateKey, buffer);
};