Projekt

Obecné

Profil

Stáhnout (2.48 KB) Statistiky
| Větev: | Revize:
1
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
(4-4/5)