Projekt

Obecné

Profil

Stáhnout (2.48 KB) Statistiky
| Větev: | Revize:
1 3a515b92 cagy
var md5 = require('create-hash/md5')
2
var RIPEMD160 = require('ripemd160')
3
var sha = require('sha.js')
4
5
var checkParameters = require('./precondition')
6
var defaultEncoding = require('./default-encoding')
7
var Buffer = require('safe-buffer').Buffer
8
var ZEROS = Buffer.alloc(128)
9
var sizes = {
10
  md5: 16,
11
  sha1: 20,
12
  sha224: 28,
13
  sha256: 32,
14
  sha384: 48,
15
  sha512: 64,
16
  rmd160: 20,
17
  ripemd160: 20
18
}
19
20
function Hmac (alg, key, saltLen) {
21
  var hash = getDigest(alg)
22
  var blocksize = (alg === 'sha512' || alg === 'sha384') ? 128 : 64
23
24
  if (key.length > blocksize) {
25
    key = hash(key)
26
  } else if (key.length < blocksize) {
27
    key = Buffer.concat([key, ZEROS], blocksize)
28
  }
29
30
  var ipad = Buffer.allocUnsafe(blocksize + sizes[alg])
31
  var opad = Buffer.allocUnsafe(blocksize + sizes[alg])
32
  for (var i = 0; i < blocksize; i++) {
33
    ipad[i] = key[i] ^ 0x36
34
    opad[i] = key[i] ^ 0x5C
35
  }
36
37
  var ipad1 = Buffer.allocUnsafe(blocksize + saltLen + 4)
38
  ipad.copy(ipad1, 0, 0, blocksize)
39
  this.ipad1 = ipad1
40
  this.ipad2 = ipad
41
  this.opad = opad
42
  this.alg = alg
43
  this.blocksize = blocksize
44
  this.hash = hash
45
  this.size = sizes[alg]
46
}
47
48
Hmac.prototype.run = function (data, ipad) {
49
  data.copy(ipad, this.blocksize)
50
  var h = this.hash(ipad)
51
  h.copy(this.opad, this.blocksize)
52
  return this.hash(this.opad)
53
}
54
55
function getDigest (alg) {
56
  function shaFunc (data) {
57
    return sha(alg).update(data).digest()
58
  }
59
  function rmd160Func (data) {
60
    return new RIPEMD160().update(data).digest()
61
  }
62
63
  if (alg === 'rmd160' || alg === 'ripemd160') return rmd160Func
64
  if (alg === 'md5') return md5
65
  return shaFunc
66
}
67
68
function pbkdf2 (password, salt, iterations, keylen, digest) {
69
  checkParameters(password, salt, iterations, keylen)
70
71
  if (!Buffer.isBuffer(password)) password = Buffer.from(password, defaultEncoding)
72
  if (!Buffer.isBuffer(salt)) salt = Buffer.from(salt, defaultEncoding)
73
74
  digest = digest || 'sha1'
75
76
  var hmac = new Hmac(digest, password, salt.length)
77
78
  var DK = Buffer.allocUnsafe(keylen)
79
  var block1 = Buffer.allocUnsafe(salt.length + 4)
80
  salt.copy(block1, 0, 0, salt.length)
81
82
  var destPos = 0
83
  var hLen = sizes[digest]
84
  var l = Math.ceil(keylen / hLen)
85
86
  for (var i = 1; i <= l; i++) {
87
    block1.writeUInt32BE(i, salt.length)
88
89
    var T = hmac.run(block1, hmac.ipad1)
90
    var U = T
91
92
    for (var j = 1; j < iterations; j++) {
93
      U = hmac.run(U, hmac.ipad2)
94
      for (var k = 0; k < hLen; k++) T[k] ^= U[k]
95
    }
96
97
    T.copy(DK, destPos)
98
    destPos += hLen
99
  }
100
101
  return DK
102
}
103
104
module.exports = pbkdf2