Skip to content

Commit

Permalink
Merge pull request #3 from kuzzleio/sha256-support
Browse files Browse the repository at this point in the history
Add sha256 support with old md5 support
  • Loading branch information
Shiranuit authored Sep 18, 2019
2 parents 7cad38d + 8828ae5 commit 6ba2eaf
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 7 deletions.
23 changes: 19 additions & 4 deletions lib/vault.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ class Vault {
return;
}

this._vaultKeyHash = crypto.createHash('md5')
this._vaultKeyHash = crypto.createHash('sha256')
.update(this._vaultKey, 'utf-8')
.digest();
this._vaultKeyHashMD5 = crypto.createHash('md5')
.update(this._vaultKey, 'utf-8')
.digest('hex')
.toUpperCase();
Expand Down Expand Up @@ -154,18 +157,30 @@ class Vault {
}

/**
* Decrypts data with AES CBC using the secret key and the initialization vector
* Decrypts data with AES CBC using the given secret key and the initialization vector
* This function keeps compatibility with old IV size (8 bytes) from 1.8.0 to 1.8.1
*/
_decryptData (data) {
_decryptDataWithKey(data, key) {
const
[ encryptedData, ivHex ] = data.split('.'),
iv = ivHex.length === 16 ? ivHex : Buffer.from(ivHex, 'hex'),
decipher = crypto.createDecipheriv('aes-256-cbc', this._vaultKeyHash, iv);
decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);

return decipher.update(encryptedData, 'hex', 'utf8') + decipher.final('utf8');
}

/**
* Decrypts data with AES CBC using the initialization vector and the sha256 hashed secret key
* or the md5 hashed secrets key if it fails with sha256
*/
_decryptData (data) {
try {
return this._decryptDataWithKey(data, this._vaultKeyHash);
} catch (e) {
return this._decryptDataWithKey(data, this._vaultKeyHashMD5);
}
}

_readJsonFile (file) {
return JSON.parse(fs.readFileSync(file, 'utf8'));
}
Expand Down
49 changes: 46 additions & 3 deletions test/vault.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ describe('Test: vault core component', () => {
clearSecrets,
encryptedSecrets,
encryptedSecretsIv8,
encryptedSecretsSha256,
encryptedSecretsSha256Iv8,
Vault,
vault;

Expand All @@ -21,6 +23,7 @@ describe('Test: vault core component', () => {
deep: { nested: { value: 'nested value' } }
};

// Encrypted secrets with MD5 hashed password
encryptedSecrets = {
aws: {
keyId: 'ac2560ec6b05098a843cdc5ab106bf99.f79775f7fd8fb7c8f456b68741414fcc',
Expand All @@ -33,7 +36,7 @@ describe('Test: vault core component', () => {
}
};

// Encrypted secrets with 8 bytes IV
// Encrypted secrets with 8 bytes IV and MD5 hashed password
encryptedSecretsIv8 = {
aws: {
keyId: '5f71b9bc33a6aea5b0263c9be88c1c4f.786ff771e2760258',
Expand All @@ -46,6 +49,32 @@ describe('Test: vault core component', () => {
}
};

// Encrypted secrets with SHA256 hashed password
encryptedSecretsSha256 = {
aws: {
keyId: 'da4e9dcf3b20ae3901211764c97b954b.4000c14b024ca76b48d922d666624eab',
secretKey: '7160329ef751a3377354586db9515173991276f5216f73b0789af214c8298f877b08ef6305c1b670c48687d5f2867bb0.d8027bacfeedb64ce54b2d13dd5558bc'
},
deep: {
nested: {
value: 'be2698fc2840a5d4eec839c5a5963b98.97492d612828b6a1974827a9781c6d35'
}
}
};

// Encrypted secrets with 8 bytes IV and SHA256 hashed password
encryptedSecretsSha256Iv8 = {
aws: {
keyId: 'b6d4f001f8825802cc550bc1b959e99c.00c8ac5ec21a6f6e',
secretKey: '1bfd3a80c7bae345b48076914f351522e2bea4dab7572c63342eb5d3a95db2e35d9d66d42d58e2ec057d264725d594ed.9c529964fbb80be1'
},
deep: {
nested: {
value: '57767336893841dec88ee5babfe591b4.1765cd733e639217'
}
}
};

fsMock = {
existsSync: sinon.stub().returns(true),
readFileSync: sinon.stub().returns(JSON.stringify(encryptedSecrets)),
Expand Down Expand Up @@ -86,17 +115,31 @@ describe('Test: vault core component', () => {
}
});

it('reads the secret file and store decrypted secrets', () => {
it('reads the secret file and store decrypted secrets with MD5 hashed password', () => {
vault.decrypt();
should(vault.secrets).match(clearSecrets);
});

it('reads the secret file and store decrypted secrets with old IV size of 8 bytes', () => {
it('reads the secret file and store decrypted secrets with old IV size of 8 bytes and MD5 hashed password', () => {
fsMock.readFileSync.returns(JSON.stringify(encryptedSecretsIv8));

vault.decrypt();
should(vault.secrets).match(clearSecrets);
});

it('reads the secret file and store decrypted secrets with SHA256 hashed password', () => {
fsMock.readFileSync.returns(JSON.stringify(encryptedSecretsSha256));

vault.decrypt();
should(vault.secrets).match(clearSecrets);
});

it('reads the secret file and store decrypted secrets with old IV size of 8 bytes and SHA256 hashed password', () => {
fsMock.readFileSync.returns(JSON.stringify(encryptedSecretsSha256Iv8));

vault.decrypt();
should(vault.secrets).match(clearSecrets);
});
});

describe('#encrypt', () => {
Expand Down

0 comments on commit 6ba2eaf

Please sign in to comment.