mirror of
https://gitlab.com/soapbox-pub/ditto.git
synced 2025-12-06 03:19:46 +00:00
Add a crypto module to convert ECDSA private CryptoKey into a public key
This commit is contained in:
parent
6430dd11ad
commit
1ed6cac1c4
2 changed files with 53 additions and 0 deletions
28
src/utils/crypto.test.ts
Normal file
28
src/utils/crypto.test.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import { assertEquals } from '@std/assert';
|
||||
|
||||
import { getEcdsaPublicKey } from '@/utils/crypto.ts';
|
||||
|
||||
Deno.test('getEcdsaPublicKey', async () => {
|
||||
const { publicKey, privateKey } = await crypto.subtle.generateKey(
|
||||
{
|
||||
name: 'ECDSA',
|
||||
namedCurve: 'P-256',
|
||||
},
|
||||
true,
|
||||
['sign', 'verify'],
|
||||
);
|
||||
|
||||
const result = await getEcdsaPublicKey(privateKey, true);
|
||||
|
||||
assertKeysEqual(result, publicKey);
|
||||
});
|
||||
|
||||
/** Assert that two CryptoKey objects are equal by value. Keys must be exportable. */
|
||||
async function assertKeysEqual(a: CryptoKey, b: CryptoKey): Promise<void> {
|
||||
const [jwk1, jwk2] = await Promise.all([
|
||||
crypto.subtle.exportKey('jwk', a),
|
||||
crypto.subtle.exportKey('jwk', b),
|
||||
]);
|
||||
|
||||
assertEquals(jwk1, jwk2);
|
||||
}
|
||||
25
src/utils/crypto.ts
Normal file
25
src/utils/crypto.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/**
|
||||
* Convert an ECDSA private key into a public key.
|
||||
* https://stackoverflow.com/a/72153942
|
||||
*/
|
||||
export async function getEcdsaPublicKey(
|
||||
privateKey: CryptoKey,
|
||||
extractable: boolean,
|
||||
): Promise<CryptoKey> {
|
||||
if (privateKey.type !== 'private') {
|
||||
throw new Error('Expected a private key.');
|
||||
}
|
||||
if (privateKey.algorithm.name !== 'ECDSA') {
|
||||
throw new Error('Expected a private key with the ECDSA algorithm.');
|
||||
}
|
||||
|
||||
const jwk = await crypto.subtle.exportKey('jwk', privateKey);
|
||||
const keyUsages: KeyUsage[] = ['verify'];
|
||||
|
||||
// Remove the private property from the JWK.
|
||||
delete jwk.d;
|
||||
jwk.key_ops = keyUsages;
|
||||
jwk.ext = extractable;
|
||||
|
||||
return crypto.subtle.importKey('jwk', jwk, privateKey.algorithm, extractable, keyUsages);
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue