From 1633a39f023b0f3e5402342cd4cc33a4f1579f36 Mon Sep 17 00:00:00 2001 From: achingbrain Date: Thu, 12 May 2022 17:42:31 +0100 Subject: [PATCH] feat: use @noble/hashes instead of node-forge for keys --- package.json | 1 + src/pbkdf2.ts | 28 ++++++++++++++-------------- test/crypto.spec.ts | 8 ++++---- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/package.json b/package.json index f3004154..7c8a9c58 100644 --- a/package.json +++ b/package.json @@ -171,6 +171,7 @@ "dependencies": { "@libp2p/interfaces": "^1.3.20", "@noble/ed25519": "^1.6.0", + "@noble/hashes": "^1.0.0", "@noble/secp256k1": "^1.5.4", "err-code": "^3.0.1", "iso-random-stream": "^2.0.0", diff --git a/src/pbkdf2.ts b/src/pbkdf2.ts index 199cfc58..1148316d 100644 --- a/src/pbkdf2.ts +++ b/src/pbkdf2.ts @@ -1,8 +1,8 @@ -// @ts-expect-error types are missing -import forgePbkdf2 from 'node-forge/lib/pbkdf2.js' -// @ts-expect-error types are missing -import forgeUtil from 'node-forge/lib/util.js' +import { pbkdf2 as pbkdf2Sync } from '@noble/hashes/pbkdf2' +import { sha256 } from '@noble/hashes/sha256' +import { sha512 } from '@noble/hashes/sha512' import errcode from 'err-code' +import { base64 } from 'multiformats/bases/base64' /** * Maps an IPFS hash name to its node-forge equivalent. @@ -12,28 +12,28 @@ import errcode from 'err-code' * @private */ const hashName = { - sha1: 'sha1', - 'sha2-256': 'sha256', - 'sha2-512': 'sha512' + 'sha2-256': sha256, + 'sha2-512': sha512 } /** * Computes the Password-Based Key Derivation Function 2. */ export default function pbkdf2 (password: string, salt: string, iterations: number, keySize: number, hash: string): string { - if (hash !== 'sha1' && hash !== 'sha2-256' && hash !== 'sha2-512') { + if (hash !== 'sha2-256' && hash !== 'sha2-512') { const types = Object.keys(hashName).join(' / ') throw errcode(new Error(`Hash '${hash}' is unknown or not supported. Must be ${types}`), 'ERR_UNSUPPORTED_HASH_TYPE') } const hasher = hashName[hash] - const dek = forgePbkdf2( + const dek = pbkdf2Sync( + hasher, password, - salt, - iterations, - keySize, - hasher + salt, { + c: iterations, + dkLen: keySize + } ) - return forgeUtil.encode64(dek, null) + return base64.encode(dek).substring(1) } diff --git a/test/crypto.spec.ts b/test/crypto.spec.ts index 242bc248..206c1f61 100644 --- a/test/crypto.spec.ts +++ b/test/crypto.spec.ts @@ -95,7 +95,7 @@ describe('libp2p-crypto', function () { describe('pbkdf2', () => { it('generates a derived password using sha1', () => { - const p1 = crypto.pbkdf2('password', 'at least 16 character salt', 500, 512 / 8, 'sha1') + const p1 = crypto.pbkdf2('password', 'at least 16 character salt', 500, 512 / 8, 'sha2-256') expect(p1).to.exist() expect(p1).to.be.a('string') }) @@ -107,9 +107,9 @@ describe('libp2p-crypto', function () { }) it('generates the same derived password with the same options', () => { - const p1 = crypto.pbkdf2('password', 'at least 16 character salt', 10, 512 / 8, 'sha1') - const p2 = crypto.pbkdf2('password', 'at least 16 character salt', 10, 512 / 8, 'sha1') - const p3 = crypto.pbkdf2('password', 'at least 16 character salt', 11, 512 / 8, 'sha1') + const p1 = crypto.pbkdf2('password', 'at least 16 character salt', 10, 512 / 8, 'sha2-256') + const p2 = crypto.pbkdf2('password', 'at least 16 character salt', 10, 512 / 8, 'sha2-256') + const p3 = crypto.pbkdf2('password', 'at least 16 character salt', 11, 512 / 8, 'sha2-256') expect(p2).to.equal(p1) expect(p3).to.not.equal(p2) })