From e1c4f0591dab814a267ae5eab2284bd13a4ad8f3 Mon Sep 17 00:00:00 2001 From: Pavel <14926950+prichodko@users.noreply.github.com> Date: Tue, 19 Jul 2022 17:45:29 +0200 Subject: [PATCH] Use built-in PBKDF2 implementation for browsers (#295) * add pbkdf2 browser implementation * use webcrypto in pbkdf2 * rename pbkdf2 file * use pbkdf2 * add changeset * revert rename * remove browser field from package.json * use `resolve.alias` for pbkdf2 if test * use `mode` in vite.config.ts Co-authored-by: Felicio Mununga --- .changeset/itchy-apes-sin.md | 5 +++ .../status-js/src/crypto/pbkdf2.browser.ts | 33 +++++++++++++++++++ .../src/utils/generate-key-from-password.ts | 3 +- packages/status-js/vite.config.ts | 20 +++++++++-- 4 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 .changeset/itchy-apes-sin.md create mode 100644 packages/status-js/src/crypto/pbkdf2.browser.ts diff --git a/.changeset/itchy-apes-sin.md b/.changeset/itchy-apes-sin.md new file mode 100644 index 00000000..da4d052a --- /dev/null +++ b/.changeset/itchy-apes-sin.md @@ -0,0 +1,5 @@ +--- +'@status-im/js': patch +--- + +use built-in crypto for pbkdf2 diff --git a/packages/status-js/src/crypto/pbkdf2.browser.ts b/packages/status-js/src/crypto/pbkdf2.browser.ts new file mode 100644 index 00000000..e248faea --- /dev/null +++ b/packages/status-js/src/crypto/pbkdf2.browser.ts @@ -0,0 +1,33 @@ +import type { pbkdf2 as pbkdf2Type } from 'ethereum-cryptography/pbkdf2' + +type PBKDF2 = typeof pbkdf2Type + +export const pbkdf2: PBKDF2 = async ( + password: Uint8Array, + salt: Uint8Array, + iterations: number, + keylen: number +): Promise => { + const cryptoKey = await window.crypto.subtle.importKey( + 'raw', + password, + { name: 'PBKDF2' }, + false, + ['deriveBits'] + ) + + const derivedKey = await window.crypto.subtle.deriveBits( + { + name: 'PBKDF2', + salt, + iterations, + hash: { + name: 'SHA-256', + }, + }, + cryptoKey, + keylen << 3 + ) + + return new Uint8Array(derivedKey) +} diff --git a/packages/status-js/src/utils/generate-key-from-password.ts b/packages/status-js/src/utils/generate-key-from-password.ts index 5be4be64..67d54d2b 100644 --- a/packages/status-js/src/utils/generate-key-from-password.ts +++ b/packages/status-js/src/utils/generate-key-from-password.ts @@ -1,6 +1,7 @@ -import { pbkdf2 } from 'ethereum-cryptography/pbkdf2' import { utf8ToBytes } from 'ethereum-cryptography/utils' +import { pbkdf2 } from '../crypto/pbkdf2.browser' + const AES_KEY_LENGTH = 32 // bytes /** diff --git a/packages/status-js/vite.config.ts b/packages/status-js/vite.config.ts index 96cb40f5..01a77a86 100644 --- a/packages/status-js/vite.config.ts +++ b/packages/status-js/vite.config.ts @@ -4,12 +4,26 @@ import { defineConfig } from 'vite' import { dependencies } from './package.json' +import type { Alias } from 'vite' + const external = [ ...Object.keys(dependencies || {}), // ...Object.keys(peerDependencies || {}), ].map(name => new RegExp(`^${name}(/.*)?`)) export default defineConfig(({ mode }) => { + const alias: Alias[] = [] + + if (mode === 'test') { + alias.push({ + /** + * Note: `happy-dom` nor `jsdom` have Crypto implemented (@see https://github.com/jsdom/jsdom/issues/1612) + */ + find: /^.*\/crypto\/pbkdf2.browser$/, + replacement: 'ethereum-cryptography/pbkdf2', + }) + } + return { build: { target: 'es2020', @@ -24,9 +38,11 @@ export default defineConfig(({ mode }) => { external, }, }, - + resolve: { + alias, + }, test: { - // environment: 'happy-dom', + environment: 'happy-dom', }, } })