Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@tsmx/secure-config-tool

Package Overview
Dependencies
Maintainers
1
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@tsmx/secure-config-tool - npm Package Compare versions

Comparing version 1.0.2 to 1.1.0

.eslintignore

3

functions/create-key.js
const crypt = require('../utils/crypt');
module.exports = function (options) {
const key = crypt.genkey();
console.log(key);
console.log(crypt.genkey(options && options.base64));
};

@@ -6,3 +6,3 @@ const crypt = require('../utils/crypt');

const verbose = options && options.verbose;
var key = null;
let key = null;
try {

@@ -15,3 +15,3 @@ key = crypt.retrieveKey(verbose);

}
var secret = null;
let secret = null;
if (options && options.secret) {

@@ -18,0 +18,0 @@ secret = options.secret;

{
"name": "@tsmx/secure-config-tool",
"version": "1.0.2",
"version": "1.1.0",
"description": "Tool for generating encrypted secure-config entries.",

@@ -5,0 +5,0 @@ "main": "secure-config-tool.js",

@@ -5,4 +5,9 @@ # [**secure-config-tool**](https://github.com/tsmx/secure-config-tool)

Generating encrypted secrets and keys for [secure-config](https://www.npmjs.com/package/@tsmx/secure-config).
Supporting command-line tool for [secure-config](https://www.npmjs.com/package/@tsmx/secure-config).
Features:
- generating keys
- encrypting secrets
- decrypting secrets (for validation/testing purposes)
## Usage

@@ -22,4 +27,4 @@

[tsmx@localhost ]$ secure-config-tool genkey
iC771qNLe+OGVcduw8fqpDIIK7lK0T5p
[tsmx@localhost ]$ export CONFIG_ENCRYPTION_KEY=iC771qNLe+OGVcduw8fqpDIIK7lK0T5p
9af7d400be4705147dc724db25bfd2513aa11d6013d7bf7bdb2bfe050593bd0f
[tsmx@localhost ]$ export CONFIG_ENCRYPTION_KEY=9af7d400be4705147dc724db25bfd2513aa11d6013d7bf7bdb2bfe050593bd0f
```

@@ -34,2 +39,9 @@

### Decrypt values
```
[tsmx@localhost ]$ secure-config-tool decrypt "ENCRYPTED|82da1c22e867d68007d66a23b7b748b3|452a2ed1105ec5607576b820b90aa49f"
MySecret
```
## Test

@@ -36,0 +48,0 @@

@@ -6,2 +6,3 @@ #!/usr/bin/env node

const createKey = require('./functions/create-key');
const decryptSecret = require('./functions/decrypt-secret');

@@ -11,3 +12,3 @@ program

.description('creates an encrypted entry for secure-config')
.option('-s, --secret <secret>', 'the secret value to be encryoted, asked if not provided')
.option('-s, --secret <secret>', 'the secret value to be encrypted, asked if not provided')
.option('-v, --verbose', 'verbose output')

@@ -24,3 +25,4 @@ .action(createSecret).on('--help', function () {

.command('genkey')
.description('generates a 32 bytes AES key for encrypting/decrypting values for secure-config')
.description('generates a 32 byte AES key for encrypting/decrypting values for secure-config and returns the hex string')
.option('-b, --base64', 'the generated key is a base64 string')
.action(createKey).on('--help', function () {

@@ -31,5 +33,17 @@ console.log('');

console.log(' $ secure-config-tool genkey');
console.log(' $ secure-config-tool genkey --export');
console.log(' $ secure-config-tool genkey --base64');
});
program
.command('decrypt <secret>')
.description('decrypts an encrypted entry for secure-config')
.option('-v, --verbose', 'verbose output')
.action(decryptSecret).on('--help', function () {
console.log('');
console.log('Examples:');
console.log('');
console.log(' $ secure-config-tool decrypt "ENCRYPTED|82da1c22e867d68007d66a23b7b748b3|452a2ed1105ec5607576b820b90aa49f"');
console.log(' $ secure-config-tool decrypt --verbose "ENCRYPTED|82da1c22e867d68007d66a23b7b748b3|452a2ed1105ec5607576b820b90aa49f"');
});
program.parse(process.argv);

@@ -7,5 +7,12 @@ describe('secure-config-tool test suite', () => {

const TEST_KEY = 'iC771qNLe+OGVcduw8fqpDIIK7lK0T5p';
const TEST_KEY_BROKEN = 'iC771qNLe+OGVcduw8fqpDIIK7lK0T';
const TEST_SECRET = 'MySecret123$';
const TEST_SECRET_ENCRYPTED = 'ENCRYPTED|f43fda7e3486b77a46b77b1c0b35e3db|9d329de17378813ffe21117360dfe3fa';
const DECRYPT_ERROR = 'Decryption failed. Please check that the encrypted secret is valid and has the form "ENCRYPTED|IV|DATA"\n' +
'Please see the docs under: https://github.com/tsmx/secure-config';
beforeEach(() => {
delete process.env['CONFIG_ENCRYPTION_KEY'];
jest.resetModules();
delete process.env['CONFIG_ENCRYPTION_KEY'];
console.log = testConsoleLog;

@@ -22,5 +29,3 @@ testOutput = [];

const crypt = require('../utils/crypt');
const text = 'TestSecret-123!';
const key = 'iC771qNLe+OGVcduw8fqpDIIK7lK0T5p';
const encrypted = crypt.encrypt(text, key);
const encrypted = crypt.encrypt(TEST_SECRET, TEST_KEY);
expect(encrypted).toBeDefined();

@@ -31,13 +36,60 @@ let parts = encrypted.split('|');

expect(parts[0]).toBe('ENCRYPTED');
const decrypted = crypt.decrypt(encrypted, key);
const decrypted = crypt.decrypt(encrypted, TEST_KEY);
expect(decrypted).toBeDefined();
expect(decrypted).toBe(text);
expect(decrypted).toBe(TEST_SECRET);
done();
});
it('tests a successful decryption', async (done) => {
const crypt = require('../utils/crypt');
const decrypted = crypt.decrypt(TEST_SECRET_ENCRYPTED, TEST_KEY);
expect(decrypted).toBeDefined();
expect(decrypted).toBe(TEST_SECRET);
done();
});
it('tests a failed decryption - illegal secret structure', async (done) => {
expect(() => {
const crypt = require('../utils/crypt');
const encrypted = '2a8660e3e6614b58b1c1b13d5db49ff0|30d052eeab498181b7071e2d5ce0e71a';
const decrypted = crypt.decrypt(encrypted, TEST_KEY);
}).toThrow(DECRYPT_ERROR);
done();
});
it('tests a failed decryption - illegal secret IV', async (done) => {
expect(() => {
const crypt = require('../utils/crypt');
const encrypted = 'ENCRYPTED|2a8660e3|30d052eeab498181b7071e2d5ce0e71a';
const decrypted = crypt.decrypt(encrypted, TEST_KEY);
}).toThrow(DECRYPT_ERROR);
done();
});
it('tests a failed decryption - illegal secret DATA', async (done) => {
expect(() => {
const crypt = require('../utils/crypt');
const encrypted = 'ENCRYPTED|2a8660e3e6614b58b1c1b13d5db49ff0|30d052eeab498181b7071e2d5ce0';
const decrypted = crypt.decrypt(encrypted, TEST_KEY);
}).toThrow(DECRYPT_ERROR);
done();
});
it('tests a successful key generation', async (done) => {
const crypt = require('../utils/crypt');
const hexReg = new RegExp('^[0-9A-F]{64}$', 'i');
const key = crypt.genkey();
expect(key).toBeDefined();
expect(key.length).toBe(64);
expect(hexReg.test(key)).toBeTruthy();
expect(Buffer.from(key, 'hex').length).toBe(32);
done();
});
it('tests a successful key generation with base64', async (done) => {
const crypt = require('../utils/crypt');
const key = crypt.genkey(true);
expect(key).toBeDefined();
expect(key.length).toBe(32);
expect(Buffer.from(key).length).toBe(32);
done();

@@ -47,3 +99,3 @@ });

it('tests a successful key retrieval', async (done) => {
process.env['CONFIG_ENCRYPTION_KEY'] = 'iC771qNLe+OGVcduw8fqpDIIK7lK0T5p';
process.env['CONFIG_ENCRYPTION_KEY'] = TEST_KEY;
const crypt = require('../utils/crypt');

@@ -60,3 +112,16 @@ expect(testOutput.length).toBe(0);

it('tests a failes key retrieval - no key found', async (done) => {
it('tests a successful key retrieval for a hexadecimal string', async (done) => {
process.env['CONFIG_ENCRYPTION_KEY'] = '9af7d400be4705147dc724db25bfd2513aa11d6013d7bf7bdb2bfe050593bd0f';
const crypt = require('../utils/crypt');
expect(testOutput.length).toBe(0);
const key = crypt.retrieveKey(true);
expect(key).toBeDefined();
expect(key.length).toBe(32);
expect(testOutput.length).toBe(1);
expect(testOutput[0].startsWith('CONFIG_ENCRYPTION_KEY found')).toBeTruthy();
expect(testOutput[0].endsWith('bd0f')).toBeTruthy();
done();
});
it('tests a failed key retrieval - no key found', async (done) => {
expect(() => {

@@ -71,3 +136,3 @@ const crypt = require('../utils/crypt');

expect(() => {
process.env['CONFIG_ENCRYPTION_KEY'] = 'iC771qNLe+OGVcduw8fqpDIIK7lK';
process.env['CONFIG_ENCRYPTION_KEY'] = TEST_KEY_BROKEN;
const crypt = require('../utils/crypt');

@@ -79,2 +144,103 @@ crypt.retrieveKey();

it('tests a successful command line key generation', async (done) => {
const createKey = require('../functions/create-key');
const hexReg = new RegExp('^[0-9A-F]{64}$', 'i');
createKey();
expect(testOutput.length).toBe(1);
expect(testOutput[0].length).toBe(64);
expect(hexReg.test(testOutput[0])).toBeTruthy();
expect(Buffer.from(testOutput[0], 'hex').length).toBe(32);
done();
});
it('tests a successful command line key generation with base64', async (done) => {
const createKey = require('../functions/create-key');
createKey({ base64: true });
expect(testOutput.length).toBe(1);
expect(testOutput[0].length).toBe(32);
expect(Buffer.from(testOutput[0]).length).toBe(32);
done();
});
it('tests a successful command line secret encryption', async (done) => {
process.env['CONFIG_ENCRYPTION_KEY'] = TEST_KEY;
const createSecret = require('../functions/create-secret');
createSecret({ secret: 'MySecret' });
expect(testOutput.length).toBe(1);
expect(testOutput[0].startsWith('ENCRYPTED|')).toBeTruthy();
done();
});
it('tests a successful command line secret encryption with verbose output', async (done) => {
process.env['CONFIG_ENCRYPTION_KEY'] = TEST_KEY;
const createSecret = require('../functions/create-secret');
createSecret({ secret: TEST_SECRET, verbose: true });
expect(testOutput.length).toBe(5);
expect(testOutput[0].endsWith('lK0T5p')).toBeTruthy();
expect(testOutput[1].startsWith('ENCRYPTED|')).toBeTruthy();
expect(testOutput[3]).toBe(TEST_SECRET);
expect(testOutput[4]).toBe('Success.');
done();
});
it('tests a failed command line secret encryption because of a missing key', async (done) => {
const mockExit = jest.spyOn(process, 'exit')
.mockImplementation((number) => { throw new Error('process.exit: ' + number); });
const createSecret = require('../functions/create-secret');
expect(() => {
createSecret({ secret: TEST_SECRET });
}).toThrow();
expect(mockExit).toHaveBeenCalledWith(-1);
mockExit.mockRestore();
done();
});
it('tests a successful command line secret decryption', async (done) => {
process.env['CONFIG_ENCRYPTION_KEY'] = TEST_KEY;
const decryptSecret = require('../functions/decrypt-secret');
decryptSecret(TEST_SECRET_ENCRYPTED, null);
expect(testOutput.length).toBe(1);
expect(testOutput[0]).toBe(TEST_SECRET);
done();
});
it('tests a successful command line secret decryption with verbose output', async (done) => {
process.env['CONFIG_ENCRYPTION_KEY'] = TEST_KEY;
const decryptSecret = require('../functions/decrypt-secret');
decryptSecret(TEST_SECRET_ENCRYPTED, { verbose: true });
expect(testOutput.length).toBe(2);
expect(testOutput[0].endsWith('lK0T5p')).toBeTruthy();
expect(testOutput[1]).toBe(TEST_SECRET);
done();
});
it('tests a failed command line secret decryption bevause of a broken secret', async (done) => {
const mockExit = jest.spyOn(process, 'exit')
.mockImplementation((number) => { throw new Error('process.exit: ' + number); });
process.env['CONFIG_ENCRYPTION_KEY'] = TEST_KEY;
const decryptSecret = require('../functions/decrypt-secret');
expect(() => {
decryptSecret('ENCRYPTED|f43fda7e3486b77a46b77b1c0b35e3db|9d329de17378813ffe21117360dfe3', null);
}).toThrow();
expect(mockExit).toHaveBeenCalledWith(-1);
mockExit.mockRestore();
expect(testOutput.length).toBe(1);
expect(testOutput[0]).toBe(DECRYPT_ERROR);
done();
});
it('tests a failed command line secret decryption bevause of a missing key', async (done) => {
const mockExit = jest.spyOn(process, 'exit')
.mockImplementation((number) => { throw new Error('process.exit: ' + number); });
const decryptSecret = require('../functions/decrypt-secret');
expect(() => {
decryptSecret(TEST_SECRET_ENCRYPTED, null);
}).toThrow();
expect(mockExit).toHaveBeenCalledWith(-1);
mockExit.mockRestore();
expect(testOutput.length).toBe(1);
expect(testOutput[0]).toBe('Environment variable CONFIG_ENCRYPTION_KEY not set.');
done();
});
});

@@ -5,6 +5,14 @@ const crypto = require('crypto');

module.exports.retrieveKey = function (verbose) {
const hexReg = new RegExp('^[0-9A-F]{64}$', 'i');
let result = null;
if (!process.env.CONFIG_ENCRYPTION_KEY) {
throw new Error('Environment variable CONFIG_ENCRYPTION_KEY not set.');
}
else if (process.env.CONFIG_ENCRYPTION_KEY.toString().length !== 32) {
else if (process.env.CONFIG_ENCRYPTION_KEY.toString().length == 32) {
result = Buffer.from(process.env.CONFIG_ENCRYPTION_KEY);
}
else if (hexReg.test(process.env.CONFIG_ENCRYPTION_KEY)) {
result = Buffer.from(process.env.CONFIG_ENCRYPTION_KEY, 'hex');
}
else {
throw new Error('CONFIG_ENCRYPTION_KEY length must be 32 bytes.');

@@ -15,4 +23,4 @@ }

}
return Buffer.from(process.env.CONFIG_ENCRYPTION_KEY);
}
return result;
};

@@ -25,18 +33,31 @@ module.exports.encrypt = function (text, key) {

return 'ENCRYPTED|' + iv.toString('hex') + '|' + encrypted.toString('hex');
}
};
module.exports.decrypt = function (text, key) {
let input = text.split('|');
input.shift();
let iv = Buffer.from(input[0], 'hex');
let encryptedText = Buffer.from(input[1], 'hex');
let decipher = crypto.createDecipheriv(algorithm, key, iv);
let decrypted = decipher.update(encryptedText);
decrypted = Buffer.concat([decrypted, decipher.final()]);
let decrypted = null;
try {
let input = text.split('|');
input.shift();
let iv = Buffer.from(input[0], 'hex');
let encryptedText = Buffer.from(input[1], 'hex');
let decipher = crypto.createDecipheriv(algorithm, key, iv);
decrypted = decipher.update(encryptedText);
decrypted = Buffer.concat([decrypted, decipher.final()]);
}
catch (error) {
throw new Error('Decryption failed. Please check that the encrypted secret is valid and has the form "ENCRYPTED|IV|DATA"\n' +
'Please see the docs under: https://github.com/tsmx/secure-config');
}
return decrypted.toString();
}
};
module.exports.genkey = function () {
return crypto.randomBytes(24)
.toString('base64');
}
module.exports.genkey = function (base64 = false) {
let result = null;
if (base64) {
result = crypto.randomBytes(24).toString('base64');
}
else {
result = crypto.randomBytes(32).toString('hex');
}
return result;
};
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc