account/generate-keys.js

145 lines
3.8 KiB
JavaScript

const NodeRSA = require('node-rsa');
const crypto = require('crypto');
const fs = require('fs-extra');
const yesno = require('yesno');
const logger = require('./logger');
require('colors');
const ALLOWED_CHARS_REGEX = /[^a-zA-Z0-9_-]/g;
async function main() {
const args = process.argv.slice(2);
if (args.length < 1) {
logger.error('Must pass in type and optional name');
usage();
return;
}
let [type, name] = args;
type = type.toLowerCase().trim();
if (name) {
name = name.toLowerCase().trim();
if (ALLOWED_CHARS_REGEX.test(name)) {
logger.error(`Invalid name. Names must only contain [^a-zA-Z0-9_-]. Got ${name}`);
return;
}
}
if (!['nex', 'service', 'account'].includes(type)) {
logger.error(`Invalid type. Expected nex, service, or account. Got ${type}`);
usage();
return;
}
if (type !== 'account' && (!name || name === '')) {
logger.error('If type is not account, a name MUST be passed');
usage();
return;
}
if (type === 'service' && name === 'account') {
logger.error('Cannot use service name \'account\'. Reserved');
usage();
return;
}
let path;
if (type === 'account') {
path = `${__dirname}/certs/service/account`;
} else {
path = `${__dirname}/certs/${type}/${name}`;
}
if (fs.pathExistsSync(path)) {
const overwrite = await yesno({
question: 'Keys found for type name, overwrite existing keys?'
});
if (!overwrite) {
logger.info('Not overwriting existing keys. Exiting program');
return;
}
}
const publicKeyPath = `${path}/public.pem`;
const privateKeyPath = `${path}/private.pem`;
const aesKeyPath = `${path}/aes.key`;
const secretKeyPath = `${path}/secret.key`;
// Ensure the output directories exist
logger.info('Creating output directories...');
fs.ensureDirSync(path);
logger.success('Created output directories!');
const key = new NodeRSA({ b: 1024 }, null, {
environment: 'browser',
encryptionScheme: {
'hash': 'sha256',
}
});
// Generate new key pair
logger.info('Generating RSA key pair...');
logger.warn('(this may take a while)')
key.generateKeyPair(1024);
logger.success('Generated RSA key pair!');
// Export the keys
logger.info('Exporting public key...');
const publicKey = key.exportKey('public');
logger.success('Exported public key!');
// Saving public key
logger.info('Saving public key to disk...');
fs.writeFileSync(publicKeyPath, publicKey);
logger.success(`Saved public key to ${publicKeyPath}!`);
logger.info('Exporting private key...');
const privateKey = key.exportKey('private');
logger.success('Exported private key!');
// Saving private key
logger.info('Saving private key to disk...');
fs.writeFileSync(privateKeyPath, privateKey);
logger.success(`Saved private key to ${privateKeyPath}!`);
// Generate new AES key
logger.info('Generating AES key...');
const aesKey = crypto.randomBytes(16);
logger.success('Generated AES key!');
// Saving AES key
logger.info('Saving AES key to disk...');
fs.writeFileSync(aesKeyPath, aesKey.toString('hex'));
logger.success(`Saved AES key to ${aesKeyPath}!`);
// Create HMAC secret key
logger.info('Generating HMAC secret...');
const secret = crypto.randomBytes(16);
logger.success('Generated RSA key pair!');
logger.info('Saving HMAC secret to disk...');
fs.writeFileSync(secretKeyPath, secret.toString('hex'));
logger.success(`Saved HMAC secret to ${secretKeyPath}!`);
logger.success('Keys generated successfully');
}
// Display usage information
function usage() {
console.log('Usage: node generate-keys.js type [name]');
console.log('Types:');
console.log(' - nex');
console.log(' - service');
console.log(' - account');
console.log('Name: Service or NEX server name. Not used in account type');
}
main().catch(logger.error);