ethers.js/packages/pbkdf2/src.ts/browser-pbkdf2.ts

56 lines
1.7 KiB
TypeScript
Raw Permalink Normal View History

2019-05-14 18:25:46 -04:00
"use strict";
import { arrayify, BytesLike, hexlify } from "@ethersproject/bytes";
2020-01-20 19:34:55 -05:00
import { computeHmac, SupportedAlgorithm } from "@ethersproject/sha2";
2019-05-14 18:25:46 -04:00
2020-11-14 17:42:36 -05:00
export function pbkdf2(password: BytesLike, salt: BytesLike, iterations: number, keylen: number, hashAlgorithm: string): string {
2019-05-14 18:25:46 -04:00
password = arrayify(password);
salt = arrayify(salt);
let hLen;
let l = 1;
const DK = new Uint8Array(keylen)
const block1 = new Uint8Array(salt.length + 4)
2019-05-14 18:25:46 -04:00
block1.set(salt);
//salt.copy(block1, 0, 0, salt.length)
let r: number;
let T: Uint8Array;
for (let i = 1; i <= l; i++) {
//block1.writeUInt32BE(i, salt.length)
block1[salt.length] = (i >> 24) & 0xff;
block1[salt.length + 1] = (i >> 16) & 0xff;
block1[salt.length + 2] = (i >> 8) & 0xff;
block1[salt.length + 3] = i & 0xff;
//let U = createHmac(password).update(block1).digest();
2020-11-14 17:42:36 -05:00
let U = arrayify(computeHmac(<SupportedAlgorithm>hashAlgorithm, password, block1));
2019-05-14 18:25:46 -04:00
if (!hLen) {
hLen = U.length
T = new Uint8Array(hLen)
l = Math.ceil(keylen / hLen)
r = keylen - (l - 1) * hLen
}
//U.copy(T, 0, 0, hLen)
T.set(U);
for (let j = 1; j < iterations; j++) {
//U = createHmac(password).update(U).digest();
2020-11-14 17:42:36 -05:00
U = arrayify(computeHmac(<SupportedAlgorithm>hashAlgorithm, password, U));
2019-05-14 18:25:46 -04:00
for (let k = 0; k < hLen; k++) T[k] ^= U[k]
}
const destPos = (i - 1) * hLen
const len = (i === l ? r : hLen)
2019-05-14 18:25:46 -04:00
//T.copy(DK, destPos, 0, len)
DK.set(arrayify(T).slice(0, len), destPos);
}
return hexlify(DK)
}