Skip to content

Instantly share code, notes, and snippets.

@vlucas
Last active May 26, 2023 13:27
Embed
What would you like to do?
Stronger Encryption and Decryption in Node.js
'use strict';
const crypto = require('crypto');
const ENCRYPTION_KEY = process.env.ENCRYPTION_KEY; // Must be 256 bits (32 characters)
const IV_LENGTH = 16; // For AES, this is always 16
function encrypt(text) {
let iv = crypto.randomBytes(IV_LENGTH);
let cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(ENCRYPTION_KEY), iv);
let encrypted = cipher.update(text);
encrypted = Buffer.concat([encrypted, cipher.final()]);
return iv.toString('hex') + ':' + encrypted.toString('hex');
}
function decrypt(text) {
let textParts = text.split(':');
let iv = Buffer.from(textParts.shift(), 'hex');
let encryptedText = Buffer.from(textParts.join(':'), 'hex');
let decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(ENCRYPTION_KEY), iv);
let decrypted = decipher.update(encryptedText);
decrypted = Buffer.concat([decrypted, decipher.final()]);
return decrypted.toString();
}
module.exports = { decrypt, encrypt };
@camsjams
Copy link

@nouman0557 up higher in this Gist I pasted a link to my GitHub repo which is a browser version of secret encryption using the native API SubtleCrypto

@nouman0557
Copy link

@camsjams Thank you

@hariprakashnagar
Copy link

hariprakashnagar commented Jul 28, 2021

Above code generating different password every time for same text, how can i validate password is correct when user login

@vlucas
Copy link
Author

vlucas commented Jul 28, 2021

@hariprakashnagar Encryption is not for password validation. It's for password storage, i.e. in a database. If you need to compare, you just pull the user record from the database by email or username, decrypt the password and check it against their input.

@DominusKelvin
Copy link

For some reasons my encryption key though its a 32 character string keeps getting rejected as a key with invalid key length

@vallyian
Copy link

vallyian commented Nov 16, 2021

@vlucas

@hariprakashnagar Encryption is not for password validation. It's for password storage, i.e. in a database. If you need to compare, you just pull the user record from the database by email or username, decrypt the password and check it against their input.

Never do this, passwords must be stored hashed (not reversible). They are verified by verifying the stored hash against the new hash generated from user input.

@codeyourwayup
Copy link

1 char=8 bits; so 256 bits equal 32 chars

@anarnoli
Copy link

anarnoli commented May 2, 2022

@neeraj87 your above code really helped me but i am getting an error like this

Error: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt
at Decipheriv.final (crypto.js:183:26)
at decryption (/Users/pankajpbaviskar/Desktop/Vishwajeet/Teams/twentyfirstsuperadmin/server/middleware/crypto.js:36:42)

below is my code to decrypt
let textParts = res.locals[0][key].split(':');
let iv = new Buffer.from(textParts[0], 'hex');
let encryptedText = new Buffer.from(textParts[1], 'hex');
let decipher = crypto.createDecipheriv('aes-256-cbc', new Buffer.from(KEY), iv);
let decrypted = decipher.update(encryptedText);
console.log(decrypted, 'first');
decrypted = Buffer.concat([decrypted, decipher.final('utf8')]);
console.log(decrypted.toString());
I think i am getting error for decipher.final() but don't know how to fix it.

Hi great gist! I'm getting two errors -

1st: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt error if I don't set the decipher to decipher.setAutoPadding(false).

2nd: If I do set it to fix the padding to false .. The decrypted text returned is along the lines of: �ㆠT��2ν��үf$}�b����� y\���Ɇ�2�Rd��_�q �o���֥�"�5T�.... Which of course is false when comparing original text before encryption to decrypted text.

Any ideas?? Why this is decrypting this way?

�ㆠT��2ν��үf$}�b����� y\���Ɇ�2�Rd��_�q �o���֥�"�5T� ��1�J���/���W5���e)�m�V�o�ג!��VVl�E��ϰ/@���ܴ^\��}�Z�Ű2C���v�T �Y��[wx'��6Yw�%���R�^Sǧh+42�Km�#�t����et���C-(� . �B��D�!_���e�0,�-fzO�Z*�ym:h��\d4����b��F�/� �d�����s �%p&l@l�[ǎ���%u��Nڴ�e��u���_�-�_�C�����~��m,���<�(��A�r�6 �a��g@ �,�5Ik��d�������.I�� ������|9 ��N{��B�sW�(�Q���MKAE��_T�H��nR}!�g� �rA�������,J��|�:�c?*�d�b��WJ6��N!S�'��-l

@music2code Any luck on your problem? I am in same situation.

@hostrings
Copy link

Thanks @vlucas - If anyone having trouble using code, I did the following.

npm install crypto

Get your 32 character passkey, you can type it yourself or go here and generate it > make sure you change Password length to 32 https://passwordsgenerator.net/

Copy paste that 32 character string into your .env file

In your .env file, put

ENCRYPTION_KEY = 'paste your 32 character string here'

Now Cut and paste all code from above into a js file eg file.js

In the file you want to use the encrypt and decrypt, use import the code like as follows

const { decrypt, encrypt } = require('./file') // path to your code that was cut and paste

and to use it test it out

let data = encrypt('hello')
console.log(data) // you will see the encrypted string
let dataD = decrypt(data)
console.log(dataD) // you will see the decrypted string 'hello'

Link Updated Password Generator: http://passwordsgenerators.net/

@chenvivian123
Copy link

The password generator that you included doesn't load anymore. You can try this one.
https://passwords-generator.org

@Vishu2108
Copy link

I am unable to run the code.....whenever I am entering the string.....it gives me an error...

@Venipa
Copy link

Venipa commented Apr 10, 2023

made this package a while ago for server side encrypted payloads to use for backend only: https://www.npmjs.com/package/encryption.js

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