Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@magician11
Last active July 7, 2017 01:22
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save magician11/4d4409ae48a380f7bdd0 to your computer and use it in GitHub Desktop.
Save magician11/4d4409ae48a380f7bdd0 to your computer and use it in GitHub Desktop.
How to encrypt a secret key from tweetnacl using scrypt.
const scrypt = require('scrypt-async');
const nacl = require('tweetnacl');
nacl.util = require('tweetnacl-util');
// utility functions
// -----------------
function printStage(stage) {
console.log(stage);
console.log('-'.repeat(stage.length));
}
function endStage() {
console.log('-'.repeat(33), '\n');
}
// -----------------
// generate a keypair for signing
// ------------------------------
const stage1 = 'Generating a keypair for signing / ID';
printStage(stage1);
const keyPair = nacl.sign.keyPair();
console.log('publicKey', nacl.util.encodeBase64(keyPair.publicKey));
console.log('secretKey', nacl.util.encodeBase64(keyPair.secretKey));
endStage();
// encrypting the private key
// --------------------------
const stage2 = 'Encrypting the private key';
printStage(stage2);
const userPassword = 'some password';
console.log(`Using password "${userPassword}"`);
const dkLen = 32;
const interruptStep = 0;
function encryptSecretKey(password, secretKey, callback) {
const salt = nacl.util.encodeBase64(nacl.randomBytes(32));
const nonce = new Uint8Array(24);
const logN = 16;
const blockSize = 8;
scrypt(password, salt, logN, blockSize, dkLen, interruptStep, (derivedKey) => {
const encryptedSecretKey = nacl.util.encodeBase64(
nacl.secretbox(secretKey, nonce, nacl.util.decodeBase64(derivedKey))
);
callback({ salt, logN, blockSize, encryptedSecretKey });
}, 'base64');
}
function decryptSecretKey(password, encryptedSecretKeyBundle, callback) {
const nonce = new Uint8Array(24);
scrypt(
password,
encryptedSecretKeyBundle.salt,
encryptedSecretKeyBundle.logN,
encryptedSecretKeyBundle.blockSize,
dkLen,
interruptStep,
(derivedKey) => {
const secretKey = nacl.secretbox.open(nacl.util.decodeBase64(
encryptedSecretKeyBundle.encryptedSecretKey), nonce, nacl.util.decodeBase64(derivedKey)
);
secretKey ? callback(nacl.util.encodeBase64(secretKey)) : callback('Decryption failed!');
}, 'base64');
}
encryptSecretKey('some password', keyPair.secretKey, (encryptedSecretKeyBundle) => {
console.log('TODO: save the following JSON object');
console.log(JSON.stringify(encryptedSecretKeyBundle));
endStage();
const stage1 = 'Decrypting the encrypted key';
printStage(stage1);
decryptSecretKey('some password', encryptedSecretKeyBundle, (secretKey) => {
console.log(secretKey);
});
});
endStage();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment