|
| 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