|
|
@ -10,6 +10,8 @@ Hash.sha256 = function(buf) { |
|
|
|
return new Buffer(hash); |
|
|
|
}; |
|
|
|
|
|
|
|
Hash.sha256.blocksize = 512; |
|
|
|
|
|
|
|
Hash.sha256sha256 = function(buf) { |
|
|
|
try { |
|
|
|
return Hash.sha256(Hash.sha256(buf)); |
|
|
@ -39,3 +41,49 @@ Hash.sha512 = function(buf) { |
|
|
|
var hash = sha512(buf); |
|
|
|
return new Buffer(hash); |
|
|
|
}; |
|
|
|
|
|
|
|
Hash.sha512.blocksize = 1024; |
|
|
|
|
|
|
|
Hash.hmac = function(hashf, data, key) { |
|
|
|
if (!Buffer.isBuffer(data) || !Buffer.isBuffer(key)) |
|
|
|
throw new Error('hash: data and key must be buffers'); |
|
|
|
|
|
|
|
//http://en.wikipedia.org/wiki/Hash-based_message_authentication_code
|
|
|
|
//http://tools.ietf.org/html/rfc4868#section-2
|
|
|
|
if (!hashf.blocksize) |
|
|
|
throw new Error('hash: Blocksize for hash function unknown'); |
|
|
|
|
|
|
|
var blocksize = hashf.blocksize/8; |
|
|
|
|
|
|
|
if (key.length > blocksize) |
|
|
|
key = hashf(key); |
|
|
|
else if (key < blocksize) { |
|
|
|
var fill = new Buffer(blocksize); |
|
|
|
fill.fill(0); |
|
|
|
key.copy(fill); |
|
|
|
key = fill; |
|
|
|
} |
|
|
|
|
|
|
|
var o_key = new Buffer(blocksize); |
|
|
|
o_key.fill(0x5c); |
|
|
|
|
|
|
|
var i_key = new Buffer(blocksize); |
|
|
|
i_key.fill(0x36); |
|
|
|
|
|
|
|
var o_key_pad = new Buffer(blocksize); |
|
|
|
var i_key_pad = new Buffer(blocksize); |
|
|
|
for (var i = 0; i < blocksize; i++) { |
|
|
|
o_key_pad[i] = o_key[i] ^ key[i]; |
|
|
|
i_key_pad[i] = i_key[i] ^ key[i]; |
|
|
|
} |
|
|
|
|
|
|
|
return hashf(Buffer.concat([o_key_pad, hashf(Buffer.concat([i_key_pad, data]))])); |
|
|
|
}; |
|
|
|
|
|
|
|
Hash.sha256hmac = function(data, key) { |
|
|
|
return Hash.hmac(Hash.sha256, data, key); |
|
|
|
}; |
|
|
|
|
|
|
|
Hash.sha512hmac = function(data, key) { |
|
|
|
return Hash.hmac(Hash.sha512, data, key); |
|
|
|
}; |
|
|
|