Skip to content
This repository has been archived by the owner on Jun 7, 2019. It is now read-only.

Commit

Permalink
🌱 Use aes-256-gcm for passphrase encryption
Browse files Browse the repository at this point in the history
Closes #452
  • Loading branch information
willclarktech committed Nov 20, 2017
1 parent 6bc06fb commit 45a0c6f
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 20 deletions.
39 changes: 23 additions & 16 deletions src/crypto/encrypt.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,45 +88,49 @@ export const decryptMessageWithSecret = (
};

/**
* @method encryptAES256CBCWithPassword
* @method encryptAES256GCMWithPassword
* @param {String} plainText utf8 - any utf8 string
* @param {String} password utf8 - the password used to encrypt the passphrase
*
* @return {Object} - { cipher: '...', iv: '...' }
* @return {Object} - { cipher: '...', iv: '...', tag: '...' }
*/

const encryptAES256CBCWithPassword = (plainText, password) => {
const encryptAES256GCMWithPassword = (plainText, password) => {
const iv = crypto.randomBytes(16);
const passwordHash = hash(password, 'utf8');
const cipher = crypto.createCipheriv('aes-256-cbc', passwordHash, iv);
const cipher = crypto.createCipheriv('aes-256-gcm', passwordHash, iv);
const firstBlock = cipher.update(plainText, 'utf8');
const encrypted = Buffer.concat([firstBlock, cipher.final()]);
const tag = cipher.getAuthTag();

return {
cipher: encrypted.toString('hex'),
iv: iv.toString('hex'),
tag: tag.toString('hex'),
};
};

/**
* @method decryptAES256CBCWithPassword
* @param {Object} Object - Object with cipher and iv as hex strings
* @param {String} Object.cipher - hex string AES-256-CBC cipher
* @method decryptAES256GCMWithPassword
* @param {Object} Object - Object with cipher, iv and tag as hex strings
* @param {String} Object.cipher - hex string AES-256-GCM cipher
* @param {String} Object.iv - hex string for the initialisation vector
* @param {String} Object.tag - hex string for the tag
* @param {String} password utf8 - the password used to encrypt the passphrase
*
* @return {String} utf8
*/

const decryptAES256CBCWithPassword = ({ cipher, iv }, password) => {
const decryptAES256GCMWithPassword = ({ cipher, iv, tag }, password) => {
const passwordHash = hash(password, 'utf8');
const decipherInit = crypto.createDecipheriv(
'aes-256-cbc',
const decipher = crypto.createDecipheriv(
'aes-256-gcm',
passwordHash,
hexToBuffer(iv),
);
const firstBlock = decipherInit.update(hexToBuffer(cipher));
const decrypted = Buffer.concat([firstBlock, decipherInit.final()]);
decipher.setAuthTag(hexToBuffer(tag));
const firstBlock = decipher.update(hexToBuffer(cipher));
const decrypted = Buffer.concat([firstBlock, decipher.final()]);

return decrypted.toString();
};
Expand All @@ -136,17 +140,20 @@ const decryptAES256CBCWithPassword = ({ cipher, iv }, password) => {
* @param {String} passphrase utf8 - twelve word secret passphrase
* @param {String} password utf8 - the password used to encrypt the passphrase
*
* @return {Object} - { cipher: '...', iv: '...' }
* @return {Object} - { cipher: '...', iv: '...', tag: '...' }
*/

export const encryptPassphraseWithPassword = encryptAES256CBCWithPassword;
export const encryptPassphraseWithPassword = encryptAES256GCMWithPassword;

/**
* @method decryptPassphraseWithPassword
* @param {Object} cipherAndIv - Object containing the encryption cipher and the iv
* @param {Object} Object - Object with cipher, iv and tag as hex strings
* @param {String} Object.cipher - hex string AES-256-GCM cipher
* @param {String} Object.iv - hex string for the initialisation vector
* @param {String} Object.tag - hex string for the tag
* @param {String} password utf8 - the password used to encrypt the passphrase
*
* @return {String}
*/

export const decryptPassphraseWithPassword = decryptAES256CBCWithPassword;
export const decryptPassphraseWithPassword = decryptAES256GCMWithPassword;
17 changes: 13 additions & 4 deletions test/crypto/encrypt.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,17 +161,26 @@ describe('encrypt', () => {
.and.be.hexString()
.and.have.length(32);
});

it('should output the tag', () => {
cipher.should.be
.type('object')
.and.have.property('tag')
.and.be.hexString()
.and.have.length(32);
});
});

describe('#decryptPassphraseWithPassword', () => {
it('should decrypt a text with a password', () => {
const cipherAndNonce = {
const cipherNonceAndTag = {
cipher:
'1c527b9408e77ae79e2ceb1ad5907ec523cd957d30c6a08dc922686e62ed98271910ca5b605f95aec98c438b6214fa7e83e3689f3fba89bfcaee937b35a3d931640afe79c353499a500f14c35bd3fd08',
iv: '89d0fa0b955219a0e6239339fbb8239f',
'331a80ab5f9cdd21e16f60c73e9b8f3c3d7f6b44dc79f60985234fde36077080726e577cb5596ab0c885bc321efc4f6cce52f5cae134b48e1b5308232563b6180858323bcb',
iv: 'e249a35bb2c2fa529fdbe349496d30ac',
tag: 'eb318b7feaa7a7540e599984bd1bb298',
};
const decrypted = decryptPassphraseWithPassword(
cipherAndNonce,
cipherNonceAndTag,
defaultPassword,
);
decrypted.should.be.eql(defaultSecret);
Expand Down

0 comments on commit 45a0c6f

Please sign in to comment.