From b0e34f3716feee0a73919a123033bad6b651ee52 Mon Sep 17 00:00:00 2001 From: Pascal Perrenoud Date: Wed, 15 May 2024 12:12:33 +0200 Subject: [PATCH] Implement PBKDF Closes #12 --- index.ts | 1 + src/pbkdf.ts | 22 ++++++++++++++++++++++ test/pbkdf.test.ts | 18 ++++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 src/pbkdf.ts create mode 100644 test/pbkdf.test.ts diff --git a/index.ts b/index.ts index 617689f..35fb776 100644 --- a/index.ts +++ b/index.ts @@ -1,3 +1,4 @@ export * as signature from 'signature' export * as boxes from 'boxes' export * as JWT from 'jwt' +export {pbkdf} from './src/pbkdf' diff --git a/src/pbkdf.ts b/src/pbkdf.ts new file mode 100644 index 0000000..2fdfc53 --- /dev/null +++ b/src/pbkdf.ts @@ -0,0 +1,22 @@ +export async function pbkdf(password: string, salt: Uint8Array, usages: KeyUsage[]): Promise { + const keyMaterial = await window.crypto.subtle.importKey( + "raw", + new TextEncoder().encode(password), + "PBKDF2", + false, + ["deriveBits", "deriveKey"], + ) + + return crypto.subtle.deriveKey( + { + name: "PBKDF2", + iterations: 250_000, + hash: "SHA-512", + salt, + }, + keyMaterial, + {name: "AES-GCM", length: 256}, + false, + usages, + ) +} diff --git a/test/pbkdf.test.ts b/test/pbkdf.test.ts new file mode 100644 index 0000000..9a076e1 --- /dev/null +++ b/test/pbkdf.test.ts @@ -0,0 +1,18 @@ +import {expect, test} from 'bun:test' + +import {pbkdf} from 'pbkdf' + +test('Fields are set correctly', async () => { + const pwd = 'password' + const salt = new TextEncoder().encode('salt') + const usages = ['unwrapKey', 'encrypt'] + + const k1 = await pbkdf(pwd, salt, usages) + expect(k1.extractable).toBeFalse() + expect(k1.type).toBe('secret') + + expect(k1.usages.length).toBe(usages.length) + for (const usage of usages) { + expect(k1.usages).toContain(usage) + } +})