Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | 1x 1x 1x 1x 1x | import { Buffer } from 'buffer'; const algorithmName = 'AES-GCM'; function extractEncryptionKey(hash: Uint8Array) { return hash.slice(0, 32); } function extractEncryptionInitVector(hash: Uint8Array) { return hash.slice(32, hash.length); } async function deriveWebCryptoKey(derivedKeyHash: Uint8Array) { const format = 'raw'; const key = extractEncryptionKey(derivedKeyHash); const extractable = false; const keyUsages: KeyUsage[] = ['encrypt', 'decrypt']; return crypto.subtle.importKey(format, key, algorithmName, extractable, keyUsages); } interface EncryptMnemonicArgs { mnemonic: string; derivedKeyHash: Uint8Array; } export async function encryptMnemonic({ mnemonic, derivedKeyHash }: EncryptMnemonicArgs) { const key = await deriveWebCryptoKey(derivedKeyHash); const iv = extractEncryptionInitVector(derivedKeyHash); const cipherArrayBuffer = await crypto.subtle.encrypt( { name: algorithmName, iv }, key, new TextEncoder().encode(mnemonic) ); return Buffer.from(cipherArrayBuffer).toString('hex'); } interface DecryptMnemonicArgs { encryptedMnemonic: string; derivedKeyHash: Uint8Array; } export async function decryptMnemonic({ encryptedMnemonic, derivedKeyHash }: DecryptMnemonicArgs) { Iif (derivedKeyHash.length !== 48) throw new Error('Key must be of length 48'); const key = await deriveWebCryptoKey(derivedKeyHash); const iv = extractEncryptionInitVector(derivedKeyHash); const algorithm = { name: algorithmName, iv }; const encryptedBuffer = Buffer.from(encryptedMnemonic, 'hex'); const decrypted = await crypto.subtle.decrypt(algorithm, key, encryptedBuffer); const textDecoder = new TextDecoder(); return textDecoder.decode(decrypted); } export function isDecryptionError(error: Error) { return String(error) === 'OperationError'; } |