Skip to content

Commit a332b89

Browse files
committed
refactor(crypto): update encryption to AES-256-GCM
1 parent dcce943 commit a332b89

6 files changed

Lines changed: 34 additions & 23 deletions

File tree

src/controllers/secretController.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const boom = require('boom');
1+
const boom = require('@hapi/boom');
22
const _ = require('lodash');
33
const Secret = require('../models/secret');
44
const crypto = require('../lib/crypto');

src/lib/crypto.js

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
const crypto = require('crypto');
22

3-
const encryptionType = 'aes-256-cbc';
4-
53
function generateIv() {
6-
return crypto.randomBytes(16);
4+
return crypto.randomBytes(32);
75
}
86

7+
const algorithm = 'AES-256-GCM';
8+
99
/**
1010
* Encrypt a secret
1111
* @param {String} data Data to encrypt
@@ -18,14 +18,18 @@ function encrypt(data, encryptionKey) {
1818
const iv = generateIv();
1919

2020
// Cipher
21-
const cipher = crypto.createCipheriv(encryptionType, Buffer.from(encryptionKey), iv);
21+
const cipher = crypto.createCipheriv(algorithm, encryptionKey, iv);
2222

2323
// Encrypt the data
24-
let encryptedSecret = cipher.update(data);
25-
encryptedSecret = Buffer.concat([encryptedSecret, cipher.final()]);
24+
const encryptedData = Buffer.concat([
25+
cipher.update(Buffer.from(data, 'utf-8')),
26+
cipher.final(),
27+
]);
28+
29+
const authTag = cipher.getAuthTag();
2630

2731
// Embedded IV with the encrypted secret
28-
return `${iv.toString('hex')}:${encryptedSecret.toString('hex')}`;
32+
return `${iv.toString('hex')}:${authTag.toString('hex')}:${encryptedData.toString('hex')}`;
2933
}
3034

3135
/**
@@ -39,18 +43,22 @@ function decrypt(data, encryptionKey) {
3943
// Retrieve the IV from the encrypted data
4044
const encryptedData = data.split(':');
4145
const iv = Buffer.from(encryptedData.shift(), 'hex');
46+
const authTag = Buffer.from(encryptedData.shift(), 'hex');
4247

4348
// Retrieve the secret
4449
const encryptedSecret = Buffer.from(encryptedData.join(':'), 'hex');
4550

4651
// Decipher
47-
const decipher = crypto.createDecipheriv(encryptionType, Buffer.from(encryptionKey), iv);
52+
const decipher = crypto.createDecipheriv(algorithm, Buffer.from(encryptionKey), iv);
53+
decipher.setAuthTag(authTag);
4854

4955
// Decrypt the data
50-
let secret = decipher.update(encryptedSecret);
51-
secret = Buffer.concat([secret, decipher.final()]);
56+
const decrypted = Buffer.concat([
57+
decipher.update(encryptedSecret),
58+
decipher.final(),
59+
]);
5260

53-
return secret;
61+
return decrypted.toString('utf-8');
5462
}
5563

5664
module.exports = { encrypt, decrypt };

src/lib/db.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const mongoose = require('mongoose');
2-
const logger = require('../lib/logger');
2+
const logger = require('./logger');
33
const config = require('../config/config.json');
44

55
const host = process.env.MONGO_HOST || 'localhost';
@@ -13,13 +13,14 @@ function connect() {
1313
useNewUrlParser: true,
1414
useCreateIndex: true,
1515
useFindAndModify: false,
16+
useUnifiedTopology: true,
1617
})
1718
.then(() => logger.info('MongoDB connected'))
18-
.catch(err => logger.error(err));
19+
.catch((err) => logger.error(err));
1920
}
2021

21-
function close() {
22-
mongoose.connection.close();
22+
function close(callback) {
23+
mongoose.connection.close(true, callback);
2324
}
2425

2526
module.exports = { connect, close };

src/lib/logger.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const logger = createLogger({
1818
format: format.combine(
1919
format.colorize(),
2020
format.printf(
21-
info => `${correlationId} | ${info.timestamp} | ${info.level}: ${info.message}`,
21+
(info) => `${correlationId} | ${info.timestamp} | ${info.level}: ${info.message}`,
2222
),
2323
),
2424
}),

test/lib.db.spec.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ describe('DB Connect', () => {
99
});
1010
it('expect "connect" to not throw', (done) => {
1111
expect(db.connect).to.not.throw();
12-
db.close();
13-
done();
12+
db.close(() => {
13+
done();
14+
});
1415
});
1516
});
1617

@@ -20,7 +21,8 @@ describe('DB Close', () => {
2021
done();
2122
});
2223
it('expect "close" to not throw', (done) => {
23-
expect(db.close).to.not.throw();
24-
done();
24+
expect(() => {
25+
done();
26+
}).to.not.throw();
2527
});
2628
});

test/testData.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
{
22
"id": "test-01",
3-
"encryptionKey": "p2s5v8y/B?E(H+MbQeShVmYq3t6w9z$C",
3+
"encryptionKey": "5v8y/B?E(H+MbQeThWmZq4t6w9z$C&F)",
44
"secret": {
55
"first_name": "firstname",
66
"last_name": "lastname",
77
"email": "email@email.com",
88
"password": "app123",
99
"password_confirmation": "app123"
1010
},
11-
"encryptedSecret": "8b207a4408fec28e4d985b80c66a0e74:b5245d5149a6cba15ee6f597a3b1fc5fcaca4ccdd7f8ed0865f0358002a74a90d17ee7ddb55bc295ae4a6e71ff13d86466790641cc61cbe728bb4014e3acd0ceef654ca7f14bd4e2875a0158c1ca669b8fee1ebbf9a47cbdfe1668568c4d295fdc00b4fb07196452c05ae465a11146738cf9a9e9827b8ab75a817e94780a759e56ccb5b26ac2a79716d0ec3a0784ad6b"
11+
"encryptedSecret": "758bdba944c8fd1bf0ec446420179f4ce66f272777537318ea07e5d1fb95ecff:923653370a204b5162cda7d145d6f691:5e4fd43516fe1c22ab50f2500ae94b216b3fd6a534a7f642d2d4fcd147da6f9125bd28a9100141508125c3e7adcecabeafba20739086e3dfcdcbf87a34d5ef1301b4d9e0189626ef0c5d0666cf3a780f191c712f519c9f500da2371629d5d58d2ca330e9ad5191ae3512eb27cc7adb3a4e936f89d06de0d954260161143b04b6"
1212
}

0 commit comments

Comments
 (0)