@emartech/easy-crypto
Advanced tools
Comparing version 3.0.0 to 3.1.0
@@ -75,3 +75,3 @@ 'use strict'; | ||
getSaltFromEncrypted(encrypted) { | ||
const cipherText = new Buffer(encrypted, CIPHERTEXT_ENCODING); | ||
const cipherText = Buffer.from(encrypted, CIPHERTEXT_ENCODING); | ||
return cipherText.slice(0, this._passwordSaltSize); | ||
@@ -99,3 +99,3 @@ } | ||
_buildDecryptParameters(key, ciphertext) { | ||
const rawCiphertext = new Buffer(ciphertext, CIPHERTEXT_ENCODING); | ||
const rawCiphertext = Buffer.from(ciphertext, CIPHERTEXT_ENCODING); | ||
const slicedRawData = this._sliceCiphertext(rawCiphertext); | ||
@@ -132,3 +132,3 @@ return this._createDecryptKeyObject(slicedRawData, key.key); | ||
const key = keyAndSalt.key; | ||
const rawPlaintext = new Buffer(plaintext, PLAINTEXT_ENCODING); | ||
const rawPlaintext = Buffer.from(plaintext, PLAINTEXT_ENCODING); | ||
return { iv, salt, rawPlaintext, key }; | ||
@@ -188,3 +188,3 @@ } | ||
_validateSaltSize(salt) { | ||
if(new Buffer(salt, CIPHERTEXT_ENCODING).length !== this._passwordSaltSize) { | ||
if(Buffer.from(salt, CIPHERTEXT_ENCODING).length !== this._passwordSaltSize) { | ||
throw new Error('Salt length must be ' + this._passwordSaltSize + '.'); | ||
@@ -191,0 +191,0 @@ } |
@@ -12,12 +12,26 @@ 'use strict'; | ||
describe('sanity check', function() { | ||
describe('examples', function() { | ||
it('should correctly decrypt encrypted data', function* () { | ||
const password = crypto.randomBytes(24).toString('hex'); | ||
const randomData = crypto.randomBytes(1024).toString('hex'); | ||
const password = crypto.randomBytes(24).toString('hex'); | ||
const randomData = [ | ||
crypto.randomBytes(1024).toString('hex'), | ||
crypto.randomBytes(1024).toString('hex'), | ||
crypto.randomBytes(1024).toString('hex') | ||
]; | ||
const encrypted = yield defaultInstance.encrypt(password, randomData); | ||
it('simple usage', function* () { | ||
const encrypted = yield defaultInstance.encrypt(password, randomData[0]); | ||
const decrypted = yield defaultInstance.decrypt(password, encrypted); | ||
expect(randomData[0]).to.eql(decrypted); | ||
}); | ||
it('advanced usage', function*() { | ||
const salt = yield defaultInstance.generateSalt(); | ||
const key = yield defaultInstance.generateKey(password, salt); | ||
const encrypted = yield randomData.map(data => defaultInstance.encryptWithKey(key, data)); | ||
const saltFromEncrypted = defaultInstance.getSaltFromEncrypted(encrypted[0]); | ||
const keyForDecryption = yield defaultInstance.generateKey(password, saltFromEncrypted); | ||
const decrypted = yield encrypted.map(data => defaultInstance.decryptWithKey(key, data)); | ||
expect(randomData).to.eql(decrypted); | ||
@@ -72,3 +86,3 @@ }); | ||
const encrypted = new Buffer(yield defaultInstance.encrypt('pw', 'data'), 'base64'); | ||
const encrypted = Buffer.from(yield defaultInstance.encrypt('pw', 'data'), 'base64'); | ||
@@ -139,3 +153,3 @@ expect(encrypted.slice(0, 12).toString('utf-8')).to.eql('AAAAAAAAAAAA'); | ||
function tamperWithCiphertext(ciphertext, index) { | ||
const rawCiphertext = new Buffer(ciphertext, 'base64'); | ||
const rawCiphertext = Buffer.from(ciphertext, 'base64'); | ||
rawCiphertext[index] = rawCiphertext[index] === 0x01 ? 0x02 : 0x01; | ||
@@ -151,3 +165,3 @@ return rawCiphertext.toString('base64'); | ||
let expectedSalt = 'A'.repeat(12); | ||
const encrypted = new Buffer(expectedSalt + '123456').toString('base64'); | ||
const encrypted = Buffer.from(expectedSalt + '123456').toString('base64'); | ||
const actualSalt = defaultInstance.getSaltFromEncrypted(encrypted); | ||
@@ -172,3 +186,3 @@ | ||
it('should return a Promise', function* () { | ||
const salt = new Buffer('A'.repeat(12)); | ||
const salt = Buffer.from('A'.repeat(12)); | ||
const key = defaultInstance.generateKey('123456', salt); | ||
@@ -179,3 +193,3 @@ expect(key).to.be.instanceOf(Promise); | ||
it('should resolve to a Key', function* () { | ||
const salt = new Buffer('A'.repeat(12)); | ||
const salt = Buffer.from('A'.repeat(12)); | ||
const key = yield defaultInstance.generateKey('123456', salt); | ||
@@ -198,3 +212,3 @@ expect(key).to.be.instanceOf(Key); | ||
it('should throw an error if the salt length is not correct', function* () { | ||
const salt = new Buffer('A'.repeat(10)); | ||
const salt = Buffer.from('A'.repeat(10)); | ||
@@ -213,3 +227,3 @@ let expectedError; | ||
it('should throw an error if the salt length is not correct', function* () { | ||
const salt = new Buffer('A'.repeat(12)); | ||
const salt = Buffer.from('A'.repeat(12)); | ||
const password = '123456'; | ||
@@ -241,3 +255,3 @@ const pbkdf2Spy = this.sandbox.spy(crypto, 'pbkdf2'); | ||
expect(salt).to.eql(new Buffer('AAAAAAAAAAAA', 'utf-8')); | ||
expect(salt).to.eql(Buffer.from('AAAAAAAAAAAA', 'utf-8')); | ||
}); | ||
@@ -311,3 +325,3 @@ | ||
}) | ||
}); | ||
@@ -318,3 +332,3 @@ function stubRandomBytes(randomBytes) { | ||
expect(length).to.eql(12); | ||
const randomBuffer = new Buffer(randomBytes[counter], 'utf-8'); | ||
const randomBuffer = Buffer.from(randomBytes[counter], 'utf-8'); | ||
counter++; | ||
@@ -321,0 +335,0 @@ return cb(null, randomBuffer); |
@@ -40,3 +40,3 @@ { | ||
}, | ||
"version": "3.0.0" | ||
"version": "3.1.0" | ||
} |
# node-easy-crypto [ ![Codeship Status for emartech/node-easy-crypto](https://codeship.com/projects/0baf8660-f4ea-0133-b502-5ef57cbd419a/status?branch=master)](https://codeship.com/projects/150193) [![Depedencies](https://david-dm.org/emartech/node-easy-crypto.svg)](https://david-dm.org/emartech/node-easy-crypto) [![Dev depedencies](https://david-dm.org/emartech/node-easy-crypto/dev-status.svg)](https://david-dm.org/emartech/node-easy-crypto#info=devDependencies&view=table) | ||
Provides simple wrappers around Node's crypto implementation. | ||
Provides simple wrappers around Node's crypto implementation. The library provides two interfaces: simple and advanced. Simple mode is designed for ease-of-use and advanced mode provides some performance benefits in certain use-cases. See below for more details. | ||
## Usage | ||
To get started just require the lib and create an instance right away. | ||
All the underlying crypto operations are the same. | ||
## Simple usage (Recommended) | ||
To get started just require the lib and create an instance right away. | ||
```js | ||
@@ -14,10 +16,2 @@ const crypto = require('crypto'); | ||
// Node 7.6 > | ||
ecrypto.encrypt(password, randomData).then(encrypted => { | ||
ecrypto.decrypt(password, encrypted).then(decrypted => { | ||
randomData === decrypted; // true | ||
}); | ||
}); | ||
// Node 7.6 =< | ||
async function exampleAsyncFunction() { | ||
@@ -31,2 +25,43 @@ const encrypted = await ecrypto.encrypt(password, randomData); | ||
## Advanced usage (Use for performance) | ||
[Key derivation](https://en.wikipedia.org/wiki/Key_derivation_function) is a resource heavy process. The simple interface abstracts this away and forces you to recompute the key before each encryption/decryption process. | ||
This interface allows you to cache the result of the key derivation. This is required if you need to encrypt/decrypt multiple times with the same derived key. Caching the key saves you the time to have to recompute it before every encryption/decryption. | ||
To get started just require the lib and create an instance right away. | ||
```js | ||
const crypto = require('crypto'); | ||
const ecrypto = require('@emartech/easy-crypto')(); | ||
const password = crypto.randomBytes(24).toString('hex'); | ||
const randomData = [ | ||
crypto.randomBytes(1024).toString('hex'), | ||
crypto.randomBytes(1024).toString('hex'), | ||
crypto.randomBytes(1024).toString('hex') | ||
]; | ||
async function example(password, data) { | ||
const salt = await ecrypto.generateSalt(); | ||
const key = await ecrypto.generateKey(password, salt); | ||
const encrypted = await Promise.all( | ||
data.map(item => ecrypto.encryptWithKey(key, item)) | ||
); | ||
const saltFromEncrypted = ecrypto.getSaltFromEncrypted(encrypted[0]); | ||
const keyForDecryption = await ecrypto.generateKey(password, saltFromEncrypted); | ||
const decrypted = await Promise.all( | ||
encrypted.map(item => ecrypto.decryptWithKey(keyForDecryption, item)) | ||
); | ||
return data.reduce((allValid, item, index) => { | ||
return allValid && item === decrypted[index]; | ||
}, true); | ||
} | ||
example(password, randomData); | ||
``` | ||
## Interface | ||
@@ -53,2 +88,17 @@ | ||
### encryptWithKey(`key`, `plaintext`) -> `ciphertext` | ||
`key` is an object returned by `generateKey`. `plaintext` must be `utf-8` encoded string. It will be "converted" to `bytes` and those will be used for the cryptographic operations. The output of this operations is `base64` encoded buffers. This will be used as the input of the `decryptWithKey` operation. This return value is a `Promise`. | ||
### decryptWithKey(`key`, `ciphertext`) -> `plaintext` | ||
`key` is an object returned by `generateKey`. `ciphertext` must be the output of the `encrypt` method. The library is not compatible with any other encryption library out of the box! The output of this operation is the original `utf-8` encoded string. This return value is a `Promise`. | ||
### generateKey(`password`, `salt`) -> `key` | ||
`password` should be any normal string. It will be used to generate the encryption key. `salt` is the buffer returned by `generateSalt` or `getSaltFromEncrypted`. These values will be used to derive a `key`. | ||
### generateSalt() -> `salt` | ||
Generates a random buffer of `passwordSaltSize` bytes. Returns a `Promise` which resolves to a `Buffer`. | ||
### getSaltFromEncrypted(`ciphertext`) -> `salt` | ||
Extracts the `salt` used for deriving the `key` which can be used to decrypt the `ciphertext`. Returns a `Buffer`. | ||
## The crypto parts | ||
@@ -72,2 +122,2 @@ The library is only a thin wrapper of node's own `crypto` module. It uses well known and battle tested encryption techniques. It provides a convenient wrapper around these functions, taking away the details of using encryption correctly. Feel free to explore the source! | ||
## Found a bug? Have a comment? | ||
Please find us, we would love your feedback! | ||
Please find us, we would love your feedback! |
26329
434
119