Blame view

node_modules/pbkdf2/lib/sync-browser.js 2.48 KB
aaac7fed   liuqimichale   add
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
  var md5 = require('create-hash/md5')
  var RIPEMD160 = require('ripemd160')
  var sha = require('sha.js')
  
  var checkParameters = require('./precondition')
  var defaultEncoding = require('./default-encoding')
  var Buffer = require('safe-buffer').Buffer
  var ZEROS = Buffer.alloc(128)
  var sizes = {
    md5: 16,
    sha1: 20,
    sha224: 28,
    sha256: 32,
    sha384: 48,
    sha512: 64,
    rmd160: 20,
    ripemd160: 20
  }
  
  function Hmac (alg, key, saltLen) {
    var hash = getDigest(alg)
    var blocksize = (alg === 'sha512' || alg === 'sha384') ? 128 : 64
  
    if (key.length > blocksize) {
      key = hash(key)
    } else if (key.length < blocksize) {
      key = Buffer.concat([key, ZEROS], blocksize)
    }
  
    var ipad = Buffer.allocUnsafe(blocksize + sizes[alg])
    var opad = Buffer.allocUnsafe(blocksize + sizes[alg])
    for (var i = 0; i < blocksize; i++) {
      ipad[i] = key[i] ^ 0x36
      opad[i] = key[i] ^ 0x5C
    }
  
    var ipad1 = Buffer.allocUnsafe(blocksize + saltLen + 4)
    ipad.copy(ipad1, 0, 0, blocksize)
    this.ipad1 = ipad1
    this.ipad2 = ipad
    this.opad = opad
    this.alg = alg
    this.blocksize = blocksize
    this.hash = hash
    this.size = sizes[alg]
  }
  
  Hmac.prototype.run = function (data, ipad) {
    data.copy(ipad, this.blocksize)
    var h = this.hash(ipad)
    h.copy(this.opad, this.blocksize)
    return this.hash(this.opad)
  }
  
  function getDigest (alg) {
    function shaFunc (data) {
      return sha(alg).update(data).digest()
    }
    function rmd160Func (data) {
      return new RIPEMD160().update(data).digest()
    }
  
    if (alg === 'rmd160' || alg === 'ripemd160') return rmd160Func
    if (alg === 'md5') return md5
    return shaFunc
  }
  
  function pbkdf2 (password, salt, iterations, keylen, digest) {
    checkParameters(password, salt, iterations, keylen)
  
    if (!Buffer.isBuffer(password)) password = Buffer.from(password, defaultEncoding)
    if (!Buffer.isBuffer(salt)) salt = Buffer.from(salt, defaultEncoding)
  
    digest = digest || 'sha1'
  
    var hmac = new Hmac(digest, password, salt.length)
  
    var DK = Buffer.allocUnsafe(keylen)
    var block1 = Buffer.allocUnsafe(salt.length + 4)
    salt.copy(block1, 0, 0, salt.length)
  
    var destPos = 0
    var hLen = sizes[digest]
    var l = Math.ceil(keylen / hLen)
  
    for (var i = 1; i <= l; i++) {
      block1.writeUInt32BE(i, salt.length)
  
      var T = hmac.run(block1, hmac.ipad1)
      var U = T
  
      for (var j = 1; j < iterations; j++) {
        U = hmac.run(U, hmac.ipad2)
        for (var k = 0; k < hLen; k++) T[k] ^= U[k]
      }
  
      T.copy(DK, destPos)
      destPos += hLen
    }
  
    return DK
  }
  
  module.exports = pbkdf2