You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
98 lines
2.3 KiB
JavaScript
98 lines
2.3 KiB
JavaScript
var Buffer = require('buffer').Buffer
|
|
var sha = require('./sha')
|
|
var sha256 = require('./sha256')
|
|
var rng = require('./rng')
|
|
var md5 = require('./md5')
|
|
|
|
var algorithms = {
|
|
sha1: sha,
|
|
sha256: sha256,
|
|
md5: md5
|
|
}
|
|
|
|
var blocksize = 64
|
|
var zeroBuffer = new Buffer(blocksize); zeroBuffer.fill(0)
|
|
function hmac(fn, key, data) {
|
|
if(!Buffer.isBuffer(key)) key = new Buffer(key)
|
|
if(!Buffer.isBuffer(data)) data = new Buffer(data)
|
|
|
|
if(key.length > blocksize) {
|
|
key = fn(key)
|
|
} else if(key.length < blocksize) {
|
|
key = Buffer.concat([key, zeroBuffer], blocksize)
|
|
}
|
|
|
|
var ipad = new Buffer(blocksize), opad = new Buffer(blocksize)
|
|
for(var i = 0; i < blocksize; i++) {
|
|
ipad[i] = key[i] ^ 0x36
|
|
opad[i] = key[i] ^ 0x5C
|
|
}
|
|
|
|
var hash = fn(Buffer.concat([ipad, data]))
|
|
return fn(Buffer.concat([opad, hash]))
|
|
}
|
|
|
|
function hash(alg, key) {
|
|
alg = alg || 'sha1'
|
|
var fn = algorithms[alg]
|
|
var bufs = []
|
|
var length = 0
|
|
if(!fn) error('algorithm:', alg, 'is not yet supported')
|
|
return {
|
|
update: function (data) {
|
|
if(!Buffer.isBuffer(data)) data = new Buffer(data)
|
|
|
|
bufs.push(data)
|
|
length += data.length
|
|
return this
|
|
},
|
|
digest: function (enc) {
|
|
var buf = Buffer.concat(bufs)
|
|
var r = key ? hmac(fn, key, buf) : fn(buf)
|
|
bufs = null
|
|
return enc ? r.toString(enc) : r
|
|
}
|
|
}
|
|
}
|
|
|
|
function error () {
|
|
var m = [].slice.call(arguments).join(' ')
|
|
throw new Error([
|
|
m,
|
|
'we accept pull requests',
|
|
'http://github.com/dominictarr/crypto-browserify'
|
|
].join('\n'))
|
|
}
|
|
|
|
exports.createHash = function (alg) { return hash(alg) }
|
|
exports.createHmac = function (alg, key) { return hash(alg, key) }
|
|
exports.randomBytes = function(size, callback) {
|
|
if (callback && callback.call) {
|
|
try {
|
|
callback.call(this, undefined, new Buffer(rng(size)))
|
|
} catch (err) { callback(err) }
|
|
} else {
|
|
return new Buffer(rng(size))
|
|
}
|
|
}
|
|
|
|
function each(a, f) {
|
|
for(var i in a)
|
|
f(a[i], i)
|
|
}
|
|
|
|
// the least I can do is make error messages for the rest of the node.js/crypto api.
|
|
each(['createCredentials'
|
|
, 'createCipher'
|
|
, 'createCipheriv'
|
|
, 'createDecipher'
|
|
, 'createDecipheriv'
|
|
, 'createSign'
|
|
, 'createVerify'
|
|
, 'createDiffieHellman'
|
|
, 'pbkdf2'], function (name) {
|
|
exports[name] = function () {
|
|
error('sorry,', name, 'is not implemented yet')
|
|
}
|
|
})
|