mirror of
https://github.com/wu736139669/Monkey-Test.git
synced 2026-08-06 06:14:53 +00:00
118 lines
2.8 KiB
JavaScript
118 lines
2.8 KiB
JavaScript
var aes = require('./aes');
|
|
var Transform = require('./cipherBase');
|
|
var inherits = require('inherits');
|
|
var modes = require('./modes');
|
|
var StreamCipher = require('./streamCipher');
|
|
var ebtk = require('./EVP_BytesToKey');
|
|
|
|
inherits(Decipher, Transform);
|
|
function Decipher(mode, key, iv) {
|
|
if (!(this instanceof Decipher)) {
|
|
return new Decipher(mode, key, iv);
|
|
}
|
|
Transform.call(this);
|
|
this._cache = new Splitter();
|
|
this._last = void 0;
|
|
this._cipher = new aes.AES(key);
|
|
this._prev = new Buffer(iv.length);
|
|
iv.copy(this._prev);
|
|
this._mode = mode;
|
|
}
|
|
Decipher.prototype._transform = function (data, _, next) {
|
|
this._cache.add(data);
|
|
var chunk;
|
|
var thing;
|
|
while ((chunk = this._cache.get())) {
|
|
thing = this._mode.decrypt(this, chunk);
|
|
this.push(thing);
|
|
}
|
|
next();
|
|
};
|
|
Decipher.prototype._flush = function (next) {
|
|
var chunk = this._cache.flush();
|
|
if (!chunk) {
|
|
return next;
|
|
}
|
|
|
|
this.push(unpad(this._mode.decrypt(this, chunk)));
|
|
|
|
next();
|
|
};
|
|
|
|
function Splitter() {
|
|
if (!(this instanceof Splitter)) {
|
|
return new Splitter();
|
|
}
|
|
this.cache = new Buffer('');
|
|
}
|
|
Splitter.prototype.add = function (data) {
|
|
this.cache = Buffer.concat([this.cache, data]);
|
|
};
|
|
|
|
Splitter.prototype.get = function () {
|
|
if (this.cache.length > 16) {
|
|
var out = this.cache.slice(0, 16);
|
|
this.cache = this.cache.slice(16);
|
|
return out;
|
|
}
|
|
return null;
|
|
};
|
|
Splitter.prototype.flush = function () {
|
|
if (this.cache.length) {
|
|
return this.cache;
|
|
}
|
|
};
|
|
function unpad(last) {
|
|
var padded = last[15];
|
|
if (padded === 16) {
|
|
return;
|
|
}
|
|
return last.slice(0, 16 - padded);
|
|
}
|
|
|
|
var modelist = {
|
|
ECB: require('./modes/ecb'),
|
|
CBC: require('./modes/cbc'),
|
|
CFB: require('./modes/cfb'),
|
|
OFB: require('./modes/ofb'),
|
|
CTR: require('./modes/ctr')
|
|
};
|
|
|
|
module.exports = function (crypto) {
|
|
function createDecipheriv(suite, password, iv) {
|
|
var config = modes[suite];
|
|
if (!config) {
|
|
throw new TypeError('invalid suite type');
|
|
}
|
|
if (typeof iv === 'string') {
|
|
iv = new Buffer(iv);
|
|
}
|
|
if (typeof password === 'string') {
|
|
password = new Buffer(password);
|
|
}
|
|
if (password.length !== config.key/8) {
|
|
throw new TypeError('invalid key length ' + password.length);
|
|
}
|
|
if (iv.length !== config.iv) {
|
|
throw new TypeError('invalid iv length ' + iv.length);
|
|
}
|
|
if (config.type === 'stream') {
|
|
return new StreamCipher(modelist[config.mode], password, iv, true);
|
|
}
|
|
return new Decipher(modelist[config.mode], password, iv);
|
|
}
|
|
|
|
function createDecipher (suite, password) {
|
|
var config = modes[suite];
|
|
if (!config) {
|
|
throw new TypeError('invalid suite type');
|
|
}
|
|
var keys = ebtk(crypto, password, config.key, config.iv);
|
|
return createDecipheriv(suite, keys.key, keys.iv);
|
|
}
|
|
return {
|
|
createDecipher: createDecipher,
|
|
createDecipheriv: createDecipheriv
|
|
};
|
|
};
|