Skip to content

Commit

Permalink
ACH asyncEncrypt and asyncDecrypt
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanxcharles committed May 16, 2016
1 parent bd6a5f6 commit ca22f17
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 2 deletions.
25 changes: 25 additions & 0 deletions lib/ach.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,18 @@
let dependencies = {
Aescbc: require('./aescbc'),
Hash: require('./hash'),
Random: require('./random'),
Workers: require('./workers'),
asink: require('asink'),
cmp: require('./cmp')
}

let inject = function (deps) {
let Aescbc = deps.Aescbc
let Hash = deps.Hash
let Random = deps.Random
let Workers = deps.Workers
let asink = deps.asink
let cmp = deps.cmp

let Ach = {}
Expand All @@ -28,6 +34,17 @@ let inject = function (deps) {
return Buffer.concat([hmacbuf, encBuf])
}

Ach.asyncEncrypt = function (messageBuf, cipherKeyBuf, ivBuf) {
return asink(function * () {
if (!ivBuf) {
ivBuf = Random.getRandomBuffer(128 / 8)
}
let args = [messageBuf, cipherKeyBuf, ivBuf]
let workersResult = yield Workers.asyncClassMethod('Ach', 'encrypt', args)
return workersResult.resbuf
}, this)
}

Ach.decrypt = function (encBuf, cipherKeyBuf) {
if (encBuf.length < (256 + 128 + 128) / 8) {
throw new Error('The encrypted data must be at least 256+128+128 bits, which is the length of the Hmac plus the iv plus the smallest encrypted data size')
Expand All @@ -41,6 +58,14 @@ let inject = function (deps) {
return Aescbc.decrypt(encBuf, cipherKeyBuf)
}

Ach.asyncDecrypt = function (encBuf, cipherKeyBuf) {
return asink(function * () {
let args = [encBuf, cipherKeyBuf]
let workersResult = yield Workers.asyncClassMethod('Ach', 'decrypt', args)
return workersResult.resbuf
}, this)
}

return Ach
}

Expand Down
4 changes: 2 additions & 2 deletions lib/workers.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ let inject = function (deps) {
let resolve = this.promisemap.get(workersResult.id).resolve
resolve(workersResult)
} else {
let error = new Error(workersResult.resbuf.toString())
let error = new Error(JSON.parse(workersResult.resbuf.toString()))
let reject = this.promisemap.get(workersResult.id).reject
reject(error)
}
Expand All @@ -108,7 +108,7 @@ let inject = function (deps) {

spawn () {
if (globalWorkers) {
console.log('WarnIng: Spooling up non-global workers.')
console.log('Warning: Spooling up non-global workers.')
}
if (process.browser) {
return this.spawnBrowser()
Expand Down
85 changes: 85 additions & 0 deletions test/ach.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
/* global describe,it */
'use strict'
let Ach = require('../lib/ach')
let should = require('chai').should()
let asink = require('asink')

describe('Ach (Aes+Cbc+Hmac)', function () {
it('should exist', function () {
should.exist(Ach)
})

describe('@encrypt', function () {
it('should encrypt data', function () {
let data = new Buffer([0])
Expand All @@ -24,6 +30,31 @@ describe('Ach (Aes+Cbc+Hmac)', function () {
})
})

describe('@asyncEncrypt', function () {
it('should encrypt data', function () {
return asink(function * () {
let data = new Buffer([0])
let cipherKey = new Buffer(256 / 8)
cipherKey.fill(0x12)
let encBuf = yield Ach.asyncEncrypt(data, cipherKey)
encBuf.length.should.equal(256 / 8 + 256 / 8)
}, this)
})

it('should encrypt this data and get a known value generated with sjcl', function () {
return asink(function * () {
let data = new Buffer('this is my test data')
let cipherKey = new Buffer(256 / 8)
cipherKey.fill(0x70)
let ivBuf = new Buffer(128 / 8)
ivBuf.fill(0x07)
let encBuf = yield Ach.asyncEncrypt(data, cipherKey, ivBuf)
let enchex = '5ca7fb171ef5001fdc26aca9ca806279200a8dd9bc3580b95d80335ed358627e07070707070707070707070707070707a1e5dd6b76089f0c055d718c9f597d22d727422cb1a28dd1a30aacb0cb008c1d'
encBuf.toString('hex').should.equal(enchex)
}, this)
})
})

describe('@decrypt', function () {
it('should throw an error of data is incorrect length', function () {
let encBuf = new Buffer('7519aff134f4fd273b41e50e6b9fac4d39b42afe6c2335551a4c06c4bdf9198d667b0dd26e935fdd5454e99ab27d8c17404199c79cb0c9d3884d2bd5bbd2b6', 'hex')
Expand Down Expand Up @@ -61,4 +92,58 @@ describe('Ach (Aes+Cbc+Hmac)', function () {
data.toString('hex').should.equal(pthex)
})
})

describe('@asyncDecrypt', function () {
it('should throw an error of data is incorrect length', function () {
return asink(function * () {
let encBuf = new Buffer('7519aff134f4fd273b41e50e6b9fac4d39b42afe6c2335551a4c06c4bdf9198d667b0dd26e935fdd5454e99ab27d8c17404199c79cb0c9d3884d2bd5bbd2b6', 'hex')
let cipherKey = new Buffer(256 / 8)
cipherKey.fill(0x12)
let error
try {
yield Ach.asyncDecrypt(encBuf, cipherKey)
} catch (err) {
error = err
}
error.message.should.equal('The encrypted data must be at least 256+128+128 bits, which is the length of the Hmac plus the iv plus the smallest encrypted data size')
}, this)
})

it('should throw an error of data for incorrect hmac', function () {
return asink(function * () {
let encBuf = new Buffer('0019aff134f4fd273b41e50e6b9fac4d39b42afe6c2335551a4c06c4bdf9198d667b0dd26e935fdd5454e99ab27d8c17404199c79cb0c9d3884d2bd5bbd2b619', 'hex')
let cipherKey = new Buffer(256 / 8)
cipherKey.fill(0x12)
let error
try {
yield Ach.asyncDecrypt(encBuf, cipherKey)
} catch (err) {
error = err
}
error.message.should.equal('Message authentication failed - Hmacs are not equivalent')
}, this)
})

it('should decrypt data', function () {
return asink(function * () {
let encBuf = new Buffer('7519aff134f4fd273b41e50e6b9fac4d39b42afe6c2335551a4c06c4bdf9198d667b0dd26e935fdd5454e99ab27d8c17404199c79cb0c9d3884d2bd5bbd2b619', 'hex')
let cipherKey = new Buffer(256 / 8)
cipherKey.fill(0x12)
let data = yield Ach.asyncDecrypt(encBuf, cipherKey)
data.toString('hex').should.equal('00')
}, this)
})

it('should decrypt this encrypted data generated by sjcl', function () {
return asink(function * () {
let ptbuf = new Buffer('this is my test data')
let pthex = ptbuf.toString('hex')
let encBuf = new Buffer('5ca7fb171ef5001fdc26aca9ca806279200a8dd9bc3580b95d80335ed358627e07070707070707070707070707070707a1e5dd6b76089f0c055d718c9f597d22d727422cb1a28dd1a30aacb0cb008c1d', 'hex')
let cipherKey = new Buffer(256 / 8)
cipherKey.fill(0x70)
let data = yield Ach.asyncDecrypt(encBuf, cipherKey)
data.toString('hex').should.equal(pthex)
}, this)
})
})
})

0 comments on commit ca22f17

Please sign in to comment.