Skip to content

Commit a5aa2e6

Browse files
committed
pbkdf2
1 parent 4998553 commit a5aa2e6

File tree

2 files changed

+79
-1
lines changed

2 files changed

+79
-1
lines changed

index.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ function each(a, f) {
2929
f(a[i], i)
3030
}
3131

32+
var p = require('./pbkdf2')(exports.createHmac)
33+
exports.pbkdf2 = p.pbkdf2
34+
exports.pbkdf2Sync = p.pbkdf2Sync
35+
36+
3237
// the least I can do is make error messages for the rest of the node.js/crypto api.
3338
each(['createCredentials'
3439
, 'createCipher'
@@ -38,7 +43,7 @@ each(['createCredentials'
3843
, 'createSign'
3944
, 'createVerify'
4045
, 'createDiffieHellman'
41-
, 'pbkdf2'], function (name) {
46+
], function (name) {
4247
exports[name] = function () {
4348
error('sorry,', name, 'is not implemented yet')
4449
}

pbkdf2.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// JavaScript PBKDF2 Implementation
2+
// Based on http://git.io/qsv2zw
3+
// Licensed under LGPL v3
4+
// Copyright (c) 2013 jduncanator
5+
6+
var Buffer = require('buffer').Buffer
7+
8+
var blocksize = 64
9+
var zeroBuffer = new Buffer(blocksize); zeroBuffer.fill(0)
10+
11+
module.exports = function (createHmac, exports) {
12+
exports = exports || {}
13+
14+
exports.pbkdf2 = function(password, salt, iterations, keylen, callback) {
15+
if('function' !== typeof callback)
16+
throw new Error('No callback provided to pbkdf2');
17+
setTimeout(function () {
18+
cb(null, exports.pbkdf2(password, salt, iterations, keylen))
19+
})
20+
}
21+
22+
exports.pbkdf2Sync = function(password, salt, iterations, keylen) {
23+
if('number' !== typeof iterations)
24+
throw new TypeError('Iterations not a number')
25+
if(iterations < 0)
26+
throw new TypeError('Bad iterations')
27+
if('number' !== typeof keylen)
28+
throw new TypeError('Key length not a number')
29+
if(keylen < 0)
30+
throw new TypeError('Bad key length')
31+
32+
var HMAC;
33+
var cplen, p = 0, i = 1, itmp = new Buffer(4), digtmp;
34+
var out = new Buffer(keylen);
35+
out.fill(0);
36+
while(keylen) {
37+
if(keylen > 20)
38+
cplen = 20;
39+
else
40+
cplen = keylen;
41+
42+
/* We are unlikely to ever use more than 256 blocks (5120 bits!)
43+
* but just in case...
44+
*/
45+
itmp[0] = (i >> 24) & 0xff;
46+
itmp[1] = (i >> 16) & 0xff;
47+
itmp[2] = (i >> 8) & 0xff;
48+
itmp[3] = i & 0xff;
49+
50+
HMAC = createHmac('sha1', password);
51+
HMAC.update(salt)
52+
HMAC.update(itmp);
53+
digtmp = HMAC.digest();
54+
digtmp.copy(out, p, 0, cplen);
55+
56+
for(var j = 1; j < iterations; j++) {
57+
HMAC = createHmac('sha1', password);
58+
HMAC.update(digtmp);
59+
digtmp = HMAC.digest();
60+
for(var k = 0; k < cplen; k++) {
61+
out[k] ^= digtmp[k];
62+
}
63+
}
64+
keylen -= cplen;
65+
i++;
66+
p += cplen;
67+
}
68+
69+
return out;
70+
}
71+
72+
return exports
73+
}

0 commit comments

Comments
 (0)