Skip to content

Instantly share code, notes, and snippets.

@siwalikm
Last active May 7, 2024 17:22
Show Gist options
  • Save siwalikm/8311cf0a287b98ef67c73c1b03b47154 to your computer and use it in GitHub Desktop.
Save siwalikm/8311cf0a287b98ef67c73c1b03b47154 to your computer and use it in GitHub Desktop.
AES-256-CBC implementation in nodeJS with built-in Crypto library
'use strict';
const crypto = require('crypto');
const ENC_KEY = "bf3c199c2470cb477d907b1e0917c17b"; // set random encryption key
const IV = "5183666c72eec9e4"; // set random initialisation vector
// ENC_KEY and IV can be generated as crypto.randomBytes(32).toString('hex');
const phrase = "who let the dogs out";
var encrypt = ((val) => {
let cipher = crypto.createCipheriv('aes-256-cbc', ENC_KEY, IV);
let encrypted = cipher.update(val, 'utf8', 'base64');
encrypted += cipher.final('base64');
return encrypted;
});
var decrypt = ((encrypted) => {
let decipher = crypto.createDecipheriv('aes-256-cbc', ENC_KEY, IV);
let decrypted = decipher.update(encrypted, 'base64', 'utf8');
return (decrypted + decipher.final('utf8'));
});
encrypted_key = encrypt(phrase);
original_phrase = decrypt(encrypted_key);
// star this gist if you found it useful
@BBregy
Copy link

BBregy commented Jan 11, 2020

how i can encrypt a file or data ? and after save that file in my file system

@siwalikm
Copy link
Author

siwalikm commented Jan 14, 2020

how I can encrypt a file or data? and after save that file in my file system

You need to use FS.read() to read a file from your filesystem and then pass it on to the encrypt function and then use FS.write() to write the encrypted key to a file in your disk. see usage

@BBregy
Copy link

BBregy commented Jan 15, 2020

i'm tried but i couldn't decrypt.

@NReilingh
Copy link

NReilingh commented Jun 25, 2020

This snippet creates an expectation that the key and IV are passed in as hex-encoded binary values. This is not what is happening -- they are instead being interpreted as UTF8 strings, and could just as easily have non-hex characters in them.

For example, your encryption key is meant to be 256 bits or 32 bytes. You have included 32 bytes of ASCII, but as a hexadecimal number it is only 16 bytes. What you want is:

const ENC_KEY = Buffer.from("bf3c199c2470cb477d907b1e0917c17bbf3c199c2470cb477d907b1e0917c17b", "hex"); // set random encryption key
const IV = Buffer.from("5183666c72eec9e45183666c72eec9e4", "hex"); // set random initialisation vector

Notice that I had to double the length of the hex numbers in order to reach the proper key length for aes-256-cbc.

This also may have been why @BBregy couldn't decrypt, assuming he was dealing with ciphertext from an external source.

@teezzan
Copy link

teezzan commented Jul 2, 2020

I got the following error

UtilityComponent.vue?beb0:91 Uncaught TypeError: crypto.createCipheriv is not a function

I am trying to use with Vuejs

@NReilingh
Copy link

@teezzan This code is for Node.js. The crypto module is part of Node's API, so if you want to use it in the browser (where I assume is where you're using Vue.js), you'll need to find a browser-compatible package that implements these parts of the Node API.

This one looks like it might work: https://www.npmjs.com/package/@ravshansbox/browser-crypto

@teezzan
Copy link

teezzan commented Jul 2, 2020

Not really. I am using webpack for bundling and I think most Node features work seemlessly.

@NReilingh
Copy link

@teezzan Webpack runs on node, but it doesn't magically port Node's C code to the javascript bundle that you are delivering to the browser. The error you are getting is proof of that. A better practice for your browser code would be to use the SubtleCrypto API.

@teezzan
Copy link

teezzan commented Jul 2, 2020

That sounds very reasonable. I had a tough day trying to make several libraries work for me. They failed in the grandest way possible. Seems like that was the problem all along.
Thank you very much for your help. I will check that out.

@sargamverma
Copy link

:"error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt

@Anyitechs
Copy link

I got the following error while working with the Algorithm.

"Error: invalid initialation vector size (must be 16 bytes)"

I already have an IV key generated, but blocked on how to increase the size to 16 bytes. Any help please?

@NReilingh
Copy link

@Anyitechs the point of an initialization vector is that it is the same size as the block size. If you are encrypting data, you need to generate an IV of the proper size. If you are decrypting data, and trying to use an IV that is not 16 bytes, then you have an incorrect assumption about either the cipher algorithm or your IV. (AES-256-CBC always has a block size of 16 bytes.)

@Anyitechs
Copy link

@NReilingh Correct! I understand all of that. I'm actually interacting with an external API and was sent an iv key on verification as credential to interact with the API, but I need to increase the byte size (as the current byte size is 8 bytes) to make subsequent requests to the server. So I need to increase the byte size of the iv key that has been sent to me already, and not generate a new iv key else I can't decrypt the data returned by the server.

@NReilingh
Copy link

@Anyitechs What I said was if you have an 8-byte IV, then the data can't be encrypted with AES-256-CBC.

Saying you want to "increase the byte size" of an existing piece of data doesn't make any sense. It's 8 bytes of data. If you want 16 bytes, you need 8 more bytes of data.

@Anyitechs
Copy link

@NReilingh Yea, I'm not saying I want to encrypt the data with AES-256-CBC. I only commented here because I need help.

And yea I have 8 bytes of data, but I want 16 bytes, I need more 8 bytes of data. Do you have any idea on how I can go about that please?

@NReilingh
Copy link

@NReilingh Yea, I'm not saying I want to encrypt the data with AES-256-CBC. I only commented here because I need help.

🤦‍♂️

@Anyitechs Try StackOverflow.

@uamaechi414
Copy link

Keep getting this error,
Error: Cannot find module 'crypto'

Any help on this please

@RifatMahmudno-1
Copy link

Keep getting this error,
Error: Cannot find module 'crypto'
Any help on this please

You have to import/require crypto module. You don't need to install it because it's built-in in nodeJS.
If your problem hasn't solved, please try to update nodejs to latest version

@abinayafs
Copy link

Hey anyone help me on this issue please

Error: Trying to add data in unsupported state
    at Decipheriv.update

@shubham04112002
Copy link

hey! @siwalikm
can you help me with this following problem.
I am provided a key which is 64 byte long, and we are supposed to use aes-256-cbc algorithm for encryption.
How should we use it for encryption, since at max we can use 32 bytes long key.
So is there any standard way of dealing with such problem, since I am not the one who is going to decrypt the data or I need to talk with that person who is going to decrypt it and ask for how is he decreasing its key length.

Kindly help!

@hongphuc5497
Copy link

Much obliged, it helped for my current case.

@dannybullo
Copy link

FYI, if someone still has problem creating random keys, this is how you can do it:

const ENC_KEY = "bf3c199c2470cb477d907b1e0917c17b"; // # Generate: crypto.randomBytes(32).toString("hex").slice(0, 32);
const IV = "5183666c72eec9e4"; //Generate: crypto.randomBytes(16).toString("hex").slice(0, 16);

Danny Bullo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment