From 7dcee2eb405c7d7fd0f3f291b6235a69a105b698 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Tue, 30 Nov 2021 09:02:26 +0000 Subject: [PATCH] Implementation of deriveKey() for NodeJS (#2021) Based on approach used by aes.ts --- src/crypto/key_passphrase.ts | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/crypto/key_passphrase.ts b/src/crypto/key_passphrase.ts index 474031160..0a86c9ab8 100644 --- a/src/crypto/key_passphrase.ts +++ b/src/crypto/key_passphrase.ts @@ -15,6 +15,10 @@ limitations under the License. */ import { randomString } from '../randomstring'; +import { getCrypto } from '../utils'; + +const subtleCrypto = (typeof window !== "undefined" && window.crypto) ? + (window.crypto.subtle || window.crypto.webkitSubtle) : null; const DEFAULT_ITERATIONS = 500000; @@ -70,11 +74,21 @@ export async function deriveKey( salt: string, iterations: number, numBits = DEFAULT_BITSIZE, +): Promise { + return subtleCrypto + ? deriveKeyBrowser(password, salt, iterations, numBits) + : deriveKeyNode(password, salt, iterations, numBits); +} + +async function deriveKeyBrowser( + password: string, + salt: string, + iterations: number, + numBits: number, ): Promise { const subtleCrypto = global.crypto.subtle; const TextEncoder = global.TextEncoder; if (!subtleCrypto || !TextEncoder) { - // TODO: Implement this for node throw new Error("Password-based backup is not avaiable on this platform"); } @@ -99,3 +113,17 @@ export async function deriveKey( return new Uint8Array(keybits); } + +async function deriveKeyNode( + password: string, + salt: string, + iterations: number, + numBits: number, +): Promise { + const crypto = getCrypto(); + if (!crypto) { + throw new Error("No usable crypto implementation"); + } + + return crypto.pbkdf2Sync(password, Buffer.from(salt, 'binary'), iterations, numBits, 'sha512'); +}