aes for browser and potentially bip38.

This commit is contained in:
Christopher Jeffrey 2016-04-30 16:21:04 -07:00
parent afee09a935
commit 22680ff235
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
3 changed files with 1246 additions and 16 deletions

1113
lib/bcoin/aes.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,7 @@ var utils = exports;
var assert = require('assert');
var bn = require('bn.js');
var util = require('util');
var crypto, hash;
var crypto, hash, aes;
/**
* Whether we're in a browser or not.
@ -25,10 +25,12 @@ utils.isBrowser =
(typeof process !== 'undefined' && process.browser)
|| typeof window !== 'undefined';
if (!utils.isBrowser)
if (!utils.isBrowser) {
crypto = require('cry' + 'pto');
else
} else {
hash = require('hash.js');
aes = require('./aes');
}
/**
* Global NOP function.
@ -376,7 +378,11 @@ utils.encrypt = function encrypt(data, passphrase) {
if (typeof passphrase === 'string')
passphrase = new Buffer(passphrase, 'utf8');
key = utils.pbkdf2key(passphrase, null, 2048, 256, 16);
key = utils.pbkdf2key(passphrase, null, 2048, 32, 16);
if (!crypto)
return aes.cbc.encrypt(data, key.key, key.iv);
cipher = crypto.createCipheriv('aes-256-cbc', key.key, key.iv);
return Buffer.concat([
@ -404,7 +410,11 @@ utils.decrypt = function decrypt(data, passphrase) {
if (typeof passphrase === 'string')
passphrase = new Buffer(passphrase, 'utf8');
key = utils.pbkdf2key(passphrase, null, 2048, 256, 16);
key = utils.pbkdf2key(passphrase, null, 2048, 32, 16);
if (!crypto)
return aes.cbc.decrypt(data, key.key, key.iv);
decipher = crypto.createDecipheriv('aes-256-cbc', key.key, key.iv);
return Buffer.concat([
@ -418,21 +428,16 @@ utils.decrypt = function decrypt(data, passphrase) {
* @param {Buffer|String} passphrase
* @param {(Buffer|String)?} salt
* @param {Number} iterations
* @param {Number} nkey - Key size in bits.
* @param {Number} niv - IV size in bytes.
* @param {Number} keySize - Key size in bits.
* @param {Number} ivSize - IV size in bytes.
* @returns {Buffer}
*/
utils.pbkdf2key = function pbkdf2key(passphrase, salt, iterations, nkey, niv) {
var key;
nkey /= 8;
key = utils.pbkdf2(passphrase, salt || '', iterations, nkey + niv);
utils.pbkdf2key = function pbkdf2key(passphrase, salt, iterations, keySize, ivSize) {
var key = utils.pbkdf2(passphrase, salt || '', iterations, keySize + ivSize);
return {
key: key.slice(0, nkey),
iv: key.slice(nkey)
key: key.slice(0, keySize),
iv: key.slice(keySize)
};
};

112
test/aes-test.js Normal file
View File

@ -0,0 +1,112 @@
var bn = require('bn.js');
var bcoin = require('../')();
var utils = bcoin.utils;
var assert = require('assert');
var aes = require('../lib/bcoin/aes');
var crypto = require('crypto');
describe('AES', function() {
function nencrypt(data, passphrase) {
var key, cipher;
assert(crypto, 'No crypto module available.');
assert(passphrase, 'No passphrase.');
if (typeof data === 'string')
data = new Buffer(data, 'utf8');
if (typeof passphrase === 'string')
passphrase = new Buffer(passphrase, 'utf8');
key = utils.pbkdf2key(passphrase, null, 2048, 32, 16);
cipher = crypto.createCipheriv('aes-256-cbc', key.key, key.iv);
return Buffer.concat([
cipher.update(data),
cipher.final()
]);
}
function ndecrypt(data, passphrase) {
var key, decipher;
assert(crypto, 'No crypto module available.');
assert(passphrase, 'No passphrase.');
if (typeof data === 'string')
data = new Buffer(data, 'hex');
if (typeof passphrase === 'string')
passphrase = new Buffer(passphrase, 'utf8');
key = utils.pbkdf2key(passphrase, null, 2048, 32, 16);
decipher = crypto.createDecipheriv('aes-256-cbc', key.key, key.iv);
return Buffer.concat([
decipher.update(data),
decipher.final()
]);
}
function encrypt(data, passphrase) {
var key, cipher;
assert(crypto, 'No crypto module available.');
assert(passphrase, 'No passphrase.');
if (typeof data === 'string')
data = new Buffer(data, 'utf8');
if (typeof passphrase === 'string')
passphrase = new Buffer(passphrase, 'utf8');
key = utils.pbkdf2key(passphrase, null, 2048, 32, 16);
return aes.cbc.encrypt(data, key.key, key.iv);
}
function decrypt(data, passphrase) {
var key, decipher;
assert(crypto, 'No crypto module available.');
assert(passphrase, 'No passphrase.');
if (typeof data === 'string')
data = new Buffer(data, 'hex');
if (typeof passphrase === 'string')
passphrase = new Buffer(passphrase, 'utf8');
key = utils.pbkdf2key(passphrase, null, 2048, 32, 16);
return aes.cbc.decrypt(data, key.key, key.iv);
}
it('should encrypt and decrypt a hash with 2 blocks', function() {
var hash = utils.sha256(new Buffer([]));
var enchash = encrypt(hash, 'foo');
var dechash = decrypt(enchash, 'foo');
var hash2 = utils.sha256(new Buffer([]));
var enchash2 = nencrypt(hash2, 'foo');
var dechash2 = ndecrypt(enchash2, 'foo');
assert.deepEqual(hash, hash2);
assert.deepEqual(enchash, enchash2);
assert.deepEqual(dechash, dechash2);
});
it('should encrypt and decrypt a hash with uneven blocks', function() {
var hash = Buffer.concat([utils.sha256(new Buffer([])), new Buffer([1,2,3])]);
var enchash = encrypt(hash, 'foo');
var dechash = decrypt(enchash, 'foo');
var hash2 = Buffer.concat([utils.sha256(new Buffer([])), new Buffer([1,2,3])]);
var enchash2 = nencrypt(hash2, 'foo');
var dechash2 = ndecrypt(enchash2, 'foo');
assert.deepEqual(hash, hash2);
assert.deepEqual(enchash, enchash2);
assert.deepEqual(dechash, dechash2);
});
});