Skip to content
This repository has been archived by the owner on Apr 27, 2023. It is now read-only.

Commit

Permalink
fix: key generation was not being done exactly right
Browse files Browse the repository at this point in the history
  • Loading branch information
jackson-dean committed Jan 27, 2023
1 parent 81e66f8 commit ee5fc38
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 35 deletions.
32 changes: 14 additions & 18 deletions libs/identity/src/lib/crypto-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,25 +40,21 @@ interface Base58CheckOptions {
network: Network;
}

// We are not using the native web crypto API to actually generate keys
// because it does not support the secp256k1 curve. Instead, we are using
// https://github.com/paulmillr/noble-secp256k1 which is a browser friendly
// alternative to the node elliptic package which is far smaller and only
// focuses on supporting the ec algorithm we are actually interested in here.
// If the web crypto API ever adds support for secp256k1, we should change
// this to use it.
//
// See the following for more info:
// https://github.com/w3c/webcrypto/issues/82
export const keygen = (): KeyPair => {
// hashToPrivateKey requires a byte array length >= 40 and <= 1024.
// 64 is chosen somewhat arbitrarily here.
// ecUtils.randomBytes uses window.crypto.getRandomValues in the browser or
// crypto.randomBytes in node.
const seedHex = ecUtils.bytesToHex(ecUtils.randomBytes(64));

// We are not using the native web crypto API to actually generate keys
// because it does not support the secp256k1 curve. Instead, we are using
// https://github.com/paulmillr/noble-secp256k1 which is a browser friendly
// alternative to the node elliptic package which is far smaller and only
// focuses on supporting the ec algorithm we are actually interested in here.
// If the web crypto API ever adds support for secp256k1, we should change
// this to use it.
//
// See the following for more info:
// https://github.com/w3c/webcrypto/issues/82
//
const privateKey = ecUtils.hashToPrivateKey(seedHex);
const privateKey = ecUtils.randomBytes(32);
const seedHex = ecUtils.bytesToHex(privateKey);

return {
seedHex,
Expand Down Expand Up @@ -105,7 +101,7 @@ export const signTx = async (
const transactionBytes = ecUtils.hexToBytes(txHex);
const hashedTxBytes = await sha256X2(transactionBytes);
const transactionHashHex = ecUtils.bytesToHex(hashedTxBytes);
const privateKey = ecUtils.hashToPrivateKey(seedHex);
const privateKey = ecUtils.hexToBytes(seedHex);
const [signatureBytes, recoveryParam] = await sign(
transactionHashHex,
privateKey
Expand Down Expand Up @@ -150,7 +146,7 @@ export const getSignedJWT = async (

const [signature] = await sign(
ecUtils.bytesToHex(await ecUtils.sha256(new TextEncoder().encode(jwt))),
ecUtils.hashToPrivateKey(seedHex)
ecUtils.hexToBytes(seedHex)
);
const encodedSignature = derToJoseEncoding(signature);

Expand Down
30 changes: 13 additions & 17 deletions libs/identity/src/lib/identity.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ describe('identity', () => {

describe('.jwt()', () => {
const testDerivedSeedHex =
'a9bf25f68e2f9302f7f41835dc6e68a483146ef996d0ff11a76b8d4dc38ee832a37bce43086f7209c8e92e1db1884ed28fceac3b9359d356445bb5cfa1ffc9b5';
'a9bf25f68e2f9302f7f41835dc6e68a483146ef996d0ff11a76b8d4dc38ee832';
const testDerivedPublicKeyBase58Check =
'BC1YLiLrdnAcK3eCR32ykwqL7aJfYDs9GPf1Ws8gpqjW78Th94uD5jJ';
const testPublicKeyBase58Check =
Expand Down Expand Up @@ -337,7 +337,7 @@ describe('identity', () => {
const jwt = await identity.jwt();
const parsedAndVerifiedJwt = verify(
jwt,
getPemEncodePublicKey(ecUtils.hashToPrivateKey(testDerivedSeedHex)),
getPemEncodePublicKey(ecUtils.hexToBytes(testDerivedSeedHex)),
{
// See: https://github.com/auth0/node-jsonwebtoken/issues/862
// tl;dr: the jsonwebtoken library doesn't support the ES256K algorithm,
Expand Down Expand Up @@ -382,7 +382,7 @@ describe('identity', () => {
const jwt = await identity.jwt();
const parsedAndVerifiedJwt = verify(
jwt,
getPemEncodePublicKey(ecUtils.hashToPrivateKey(testDerivedSeedHex)),
getPemEncodePublicKey(ecUtils.hexToBytes(testDerivedSeedHex)),
{
// See: https://github.com/auth0/node-jsonwebtoken/issues/862
// tl;dr: the jsonwebtoken library doesn't support the ES256K algorithm,
Expand Down Expand Up @@ -421,23 +421,19 @@ describe('identity', () => {

it('is invalid when verified with the wrong public key', async () => {
const badSeedHex =
'b3302883522db5863ded181b727153ddb1a7cd1deb5eaa00d406f9e08ae0bfe8024e889deab4a48026141cc1faaea55e0a28e3d87d9fe70cf60a98110110ea34';
'b3302883522db5863ded181b727153ddb1a7cd1deb5eaa00d406f9e08ae0bfe8';
const jwt = await identity.jwt();
let errorMessage = '';
try {
verify(
jwt,
getPemEncodePublicKey(ecUtils.hashToPrivateKey(badSeedHex)),
{
// See: https://github.com/auth0/node-jsonwebtoken/issues/862
// tl;dr: the jsonwebtoken library doesn't support the ES256K algorithm,
// even though this is the correct algorithm for JWTs signed
// with secp256k1 keys: https://www.rfc-editor.org/rfc/rfc8812.html#name-jose-algorithms-registratio
// as a workaround, we can use this flag to force it to accept and
// verify signatures generated with secp256k1 keys
allowInvalidAsymmetricKeyTypes: true,
}
);
verify(jwt, getPemEncodePublicKey(ecUtils.hexToBytes(badSeedHex)), {
// See: https://github.com/auth0/node-jsonwebtoken/issues/862
// tl;dr: the jsonwebtoken library doesn't support the ES256K algorithm,
// even though this is the correct algorithm for JWTs signed
// with secp256k1 keys: https://www.rfc-editor.org/rfc/rfc8812.html#name-jose-algorithms-registratio
// as a workaround, we can use this flag to force it to accept and
// verify signatures generated with secp256k1 keys
allowInvalidAsymmetricKeyTypes: true,
});
} catch (e: any) {
errorMessage = e.toString();
}
Expand Down

0 comments on commit ee5fc38

Please sign in to comment.