1

I am new to topics related to encoding and I am having troubles with being able to convert my scryptsync key into something createCipheriv (Crypto library integrated into Nodejs) can use in the iv parameter.

const algorithm = 'aes-256-gcm';
var text = 'default'
var encrypted = secret;

class Auth
{

SignUp(pass)
{
    console.log(pass);

    var pair = ec.genKeyPair(); 

    text = pair.getPrivate.toString('hex');

    var key = crypto.scryptSync(pass, 'baethrowssalt', 32);

    console.log(`The key is:${key}`); //this is not a string

    key=key.toString('hex');

    var cipher = crypto.createCipheriv(algorithm, key);  

    var encrypted = cipher.update(text, 'hex', 'hex') + cipher.final('hex');

    fs.writeFileSync(file, encrypted);

    return alert(`Close and reopen your app to integrate your wallet securely`);
}

as you can see above, I tried converting the scryptSync return to string hex so that createCipheriv is willing to use it, but I get the following error:

pass is passrig
passrig
The key is:�→A�r;yR�����▲�h�8��f�����v�A�,
TypeError [ERR_INVALID_ARG_TYPE]: The "iv" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received undefined
    at Cipheriv.createCipherWithIV (internal/crypto/cipher.js:120:29)
    at new Cipheriv (internal/crypto/cipher.js:227:22)
    at Object.createCipheriv (crypto.js:117:10)

So my question contains two parts: how can I use scryptSync with the createCipheriv? To help me understand, what are the reasons behind your solutions?

4N0M41Y
  • 324
  • 1
  • 4
  • 12

1 Answers1

1

I've created an example that encrypts some data using the algorithm aes-256-gcm and uses crypto.scryptSync to derive the key from a password.

The steps are as follows:

  1. Derive our key from our password using crypto.scryptSync.
  2. Create an IV using crypto.randomBytes.
  3. Use our key and iv to encrypt the plaintext using our encrypt function.
  4. Test our encrypted data by decrypting using our decrypt function.

This code is as follows:

const crypto = require("crypto");
const Algorithm = "aes-256-gcm";

function encrypt(plainText, key, iv) {
    const cipher = crypto.createCipheriv(Algorithm, key, iv);
    return { encrypted: Buffer.concat([cipher.update(plainText), cipher.final()]), authTag: cipher.getAuthTag() }
}

function decrypt(encrypted, key, iv, authTag) {
    const decipher = crypto.createDecipheriv(Algorithm, key, iv).setAuthTag(authTag);
    return Buffer.concat([decipher.update(encrypted), decipher.final()]);
}

const password = "Speak Friend and Enter";
const plainText = "There is nothing either good or bad but thinking makes it so.";

const salt = crypto.randomBytes(32);

// Create an encryption key from our password, ensuring it is 32 bytes long - AES-256 needs a 256 bit (32 byte) key 
const KEY = crypto.scryptSync(password, salt, 32);
const IV = crypto.randomBytes(16);

console.log("Key (derived from password, hex):", KEY.toString("hex"));
console.log("IV (hex):", IV.toString("hex"));
console.log("Plaintext:", plainText);
const { encrypted, authTag } = encrypt(plainText, KEY, IV);
console.log("Encrypted (hex):", encrypted.toString("hex"));
const decrypted = decrypt(encrypted, KEY, IV, authTag)
console.log("Decrypted:", decrypted.toString("utf-8"));
Terry Lennox
  • 29,471
  • 5
  • 28
  • 40
  • 1
    Oh my god, you are a legend. So I get the sense the IV is just an extra parameter that encrypts along side the key. But say hypothetically, I want the same hash to generate every time. So I will have to store the IV in plaintext as well for future decrypting of the message? – 4N0M41Y Apr 21 '21 at 07:41
  • and is the AuthTag necessary? – 4N0M41Y Apr 21 '21 at 07:46
  • The IV is used to ensure that the same key and plaintext don't encrypt to the same value. This makes it much more robust cryptographically. You'll always need to store the IV with the encrypted bytes (as well as the auth tag) – Terry Lennox Apr 21 '21 at 07:46
  • We need to retain the auth tag if we're using GCM mode. It allows us to verify the encrypted data is valid and has not been tampered with. I hope that helps! – Terry Lennox Apr 21 '21 at 07:48
  • 1
    This makes the river flow smoother in my head. Thank you for explaining it. – 4N0M41Y Apr 21 '21 at 08:02
  • Glad to help, have a nice day!! – Terry Lennox Apr 21 '21 at 08:30
  • 1
    Hey Terry, I posted a new question to follow up with this. I am having problems with retrieving the Hex string of the IV from the file and converting it to binary to use in createDecipher. It's giving me repeated messages of "undefined". Do you think you can take a look please? https://stackoverflow.com/questions/67238509/initialization-vector-iv-tostringhex-write-to-file-read-from-file – 4N0M41Y Apr 24 '21 at 05:38
  • Sure thing, I will do – Terry Lennox Apr 24 '21 at 06:28