Last active
July 7, 2017 01:22
-
-
Save magician11/4d4409ae48a380f7bdd0 to your computer and use it in GitHub Desktop.
How to encrypt a secret key from tweetnacl using scrypt.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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