1 | var sizes = {
|
2 | md5: 16,
|
3 | sha1: 20,
|
4 | sha224: 28,
|
5 | sha256: 32,
|
6 | sha384: 48,
|
7 | sha512: 64,
|
8 | rmd160: 20,
|
9 | ripemd160: 20
|
10 | }
|
11 |
|
12 | var createHmac = require('create-hmac')
|
13 | var checkParameters = require('../lib/precondition')
|
14 | var defaultEncoding = require('../lib/default-encoding')
|
15 | var Buffer = require('safe-buffer').Buffer
|
16 | module.exports = pbkdf2
|
17 | function pbkdf2 (password, salt, iterations, keylen, digest) {
|
18 | if (!Buffer.isBuffer(password)) password = Buffer.from(password, defaultEncoding)
|
19 | if (!Buffer.isBuffer(salt)) salt = Buffer.from(salt, defaultEncoding)
|
20 |
|
21 | checkParameters(iterations, keylen)
|
22 |
|
23 | digest = digest || 'sha1'
|
24 |
|
25 | var DK = Buffer.allocUnsafe(keylen)
|
26 | var block1 = Buffer.allocUnsafe(salt.length + 4)
|
27 | salt.copy(block1, 0, 0, salt.length)
|
28 |
|
29 | var U, j, destPos, len
|
30 |
|
31 | var hLen = sizes[digest]
|
32 | var T = Buffer.allocUnsafe(hLen)
|
33 | var l = Math.ceil(keylen / hLen)
|
34 | var r = keylen - (l - 1) * hLen
|
35 |
|
36 | for (var i = 1; i <= l; i++) {
|
37 | block1.writeUInt32BE(i, salt.length)
|
38 | U = createHmac(digest, password).update(block1).digest()
|
39 |
|
40 | U.copy(T, 0, 0, hLen)
|
41 |
|
42 | for (j = 1; j < iterations; j++) {
|
43 | U = createHmac(digest, password).update(U).digest()
|
44 | for (var k = 0; k < hLen; k++) T[k] ^= U[k]
|
45 | }
|
46 |
|
47 | destPos = (i - 1) * hLen
|
48 | len = (i === l ? r : hLen)
|
49 | T.copy(DK, destPos, 0, len)
|
50 | }
|
51 |
|
52 | return DK
|
53 | }
|