Skip to content

Instantly share code, notes, and snippets.

@Tiriel
Last active June 21, 2024 07:53
Show Gist options
  • Save Tiriel/bff8b06cb3359bba5f9e9ba1f9fc52c0 to your computer and use it in GitHub Desktop.
Save Tiriel/bff8b06cb3359bba5f9e9ba1f9fc52c0 to your computer and use it in GitHub Desktop.
Symetric encryption/decryption for PHP and NodeJS communication
'use strict';
const crypto = require('crypto');
const AES_METHOD = 'aes-256-cbc';
const IV_LENGTH = 16; // For AES, this is always 16, checked with php
const password = 'lbwyBzfgzUIvXZFShJuikaWvLJhIVq36'; // Must be 256 bytes (32 characters)
function encrypt(text, password) {
if (process.versions.openssl <= '1.0.1f') {
throw new Error('OpenSSL Version too old, vulnerability to Heartbleed')
}
let iv = crypto.randomBytes(IV_LENGTH);
let cipher = crypto.createCipheriv(AES_METHOD, new Buffer(password), 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 = new Buffer(textParts.shift(), 'hex');
let encryptedText = new Buffer(textParts.join(':'), 'hex');
let decipher = crypto.createDecipheriv('aes-256-cbc', new Buffer($password), iv);
let decrypted = decipher.update(encryptedText);
decrypted = Buffer.concat([decrypted, decipher.final()]);
return decrypted.toString();
}
<?php
define('AES_METHOD', 'aes-256-cbc');
$password = 'lbwyBzfgzUIvXZFShJuikaWvLJhIVq36';
function encrypt($message, $password)
{
if (OPENSSL_VERSION_NUMBER <= 268443727) {
throw new RuntimeException('OpenSSL Version too old, vulnerability to Heartbleed');
}
$iv_size = openssl_cipher_iv_length(AES_METHOD);
$iv = openssl_random_pseudo_bytes($iv_size);
$ciphertext = openssl_encrypt($message, AES_METHOD, $password, OPENSSL_RAW_DATA, $iv);
$ciphertext_hex = bin2hex($ciphertext);
$iv_hex = bin2hex($iv);
return "$iv_hex:$ciphertext_hex";
}
function decrypt($ciphered, $password) {
$iv_size = openssl_cipher_iv_length(AES_METHOD);
$data = explode(":", $ciphered);
$iv = hex2bin($data[0]);
$ciphertext = hex2bin($data[1]);
return openssl_decrypt($ciphertext, AES_METHOD, $password, OPENSSL_RAW_DATA, $iv);
}
@elzix
Copy link

elzix commented Mar 11, 2021

You're a lifesaver, thanks @Tiriel.

@Rake076
Copy link

Rake076 commented Mar 22, 2021

For newbies like me, in line 10 in encryption.js, the function takes two arguments namely text and password. password is the constant key in the file, while text is the password you will give the function to encrypt.

Moreover, I had to change $password to password in line 28.

@iNilo
Copy link

iNilo commented Feb 22, 2022

Fixed the .js decrypt function

function decrypt(text, password){
    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(password), iv);
    let decrypted = decipher.update(encryptedText);

    decrypted = Buffer.concat([decrypted, decipher.final()]);

    return decrypted.toString();
}

@ajayalag1974
Copy link

ajayalag1974 commented Jun 13, 2022

Hello,

Thanks for implementation in PHP & NodeJS.

But now i need implementation of decryption in Browser Javascript using CryptoJS library, i have written below code but its not working, just returning empty string, see if any body can make it work:

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
<script>
function decrypt (encrypted) {
	encrypted = encrypted.split(':');
	let key = CryptoJS.enc.Utf8.parse('1234567890abcdefghijklmnopqrstuv');
	let iv = CryptoJS.enc.Hex.parse(encrypted.shift());
	let data = CryptoJS.enc.Hex.parse(encrypted.join(':'));
	data = CryptoJS.AES.decrypt({
            ciphertext: data
        },key,{iv:iv}).toString(CryptoJS.enc.Utf8);
        return data;
}
</script>

EDITED: The above code is now working, just have to provide "data" (actual encrypted string) inside an object under key "ciphertext" as a first paramater to decrypt function instead of directly passing "data".

@SATZPrincess
Copy link

@bikash-das
Copy link

How can I make the above code work for large files? I get different chunks when using php and nodejs.

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