Skip to content

Instantly share code, notes, and snippets.

@joashp
Created September 4, 2015 15:59
Show Gist options
  • Select an option

  • Save joashp/a1ae9cb30fa533f4ad94 to your computer and use it in GitHub Desktop.

Select an option

Save joashp/a1ae9cb30fa533f4ad94 to your computer and use it in GitHub Desktop.
Simple PHP encrypt and decrypt using OpenSSL
<?php
/**
* simple method to encrypt or decrypt a plain text string
* initialization vector(IV) has to be the same when encrypting and decrypting
*
* @param string $action: can be 'encrypt' or 'decrypt'
* @param string $string: string to encrypt or decrypt
*
* @return string
*/
function encrypt_decrypt($action, $string) {
$output = false;
$encrypt_method = "AES-256-CBC";
$secret_key = 'This is my secret key';
$secret_iv = 'This is my secret iv';
// hash
$key = hash('sha256', $secret_key);
// iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning
$iv = substr(hash('sha256', $secret_iv), 0, 16);
if ( $action == 'encrypt' ) {
$output = openssl_encrypt($string, $encrypt_method, $key, 0, $iv);
$output = base64_encode($output);
} else if( $action == 'decrypt' ) {
$output = openssl_decrypt(base64_decode($string), $encrypt_method, $key, 0, $iv);
}
return $output;
}
$plain_txt = "This is my plain text";
echo "Plain Text =" .$plain_txt. "\n";
$encrypted_txt = encrypt_decrypt('encrypt', $plain_txt);
echo "Encrypted Text = " .$encrypted_txt. "\n";
$decrypted_txt = encrypt_decrypt('decrypt', $encrypted_txt);
echo "Decrypted Text =" .$decrypted_txt. "\n";
if ( $plain_txt === $decrypted_txt ) echo "SUCCESS";
else echo "FAILED";
echo "\n";
?>
@crsland

crsland commented Aug 7, 2017

Copy link
Copy Markdown

Like this gist, I don't think you need line 26 though. openssl_encrypt will return a base64 encoded string with the given parameters

@cyth319

cyth319 commented Sep 1, 2017

Copy link
Copy Markdown

thank you thank you thank you thank you thank you

@sourovroy

Copy link
Copy Markdown

Thank you very much, It helps me

@kidx5452

kidx5452 commented Oct 13, 2017

Copy link
Copy Markdown

I'm using nodejs v6.
This is my code for decrypt by nodejs when using php to encrypt

PHP
$encrypt_method = "AES-256-CBC"; $secret_key = '6818f23eef19d38dad1d2729991f6368'; $secret_iv = '0ac35e3823616c810f86e526d1ed59e7'; $enc = 'a1pORHBTOEdaV1BsZTFXYUF6cXlsUGV4VVp4bUpJRHlzL2Jma0VMaGtmNVIzRUZ1VmNUbTZWVlo5cGczQUxiRmQvYXIzK0p0R1BkdnM0MU1PaU1qcmRkRmZXUW1PYjdQRHIwRDRhN2ZHRHZUWVllUktMQW1lQkNvamxnTlUwbEd5MmpsMXpORzhGS3JYY3hlRnJpL1pzQllhL28xVllYMGEwRUFwcG1uY1pHMW05cWVUd2ZpM3NaekxjNjE0aDhoZkVDRHc3cktOY3ZzNWtOeHJldXhnQjB3ekhXeGFQZElOek9MNkFjdDkrVWZQcFlYRW9KN0lvT2N2TmJXcXM0bw=='; $key = hash('sha256', $secret_key); // iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning $iv = substr(hash('sha256', $secret_iv), 0, 16); $output = openssl_decrypt(base64_decode($enc), $encrypt_method, $key, 0, $iv); echo $output;

Output: EAAEug8sk8GgBAC0XZCsp6KB1ZAaL2sSAuDEELVLc5tWZBJW2EQ0WmBCdZBAkimZAgCCIEeZB4lnwSGNk0v0SScThjBbWoMuVWJqUqgSAV75JK0kcYh24ZAqKvkEirzIEEVjgu2QqFdJxuWfDX5a58y5mgAP7BPFPgKEZBYmFVBHJZBbLT2Ye9GYaR
PHP can be decrypt.

NodeJS:
`var crypto = require('crypto');
var CryptoJS = require("crypto-js");
var key = '6818f23eef19d38dad1d2729991f6368';
var iv = '0ac35e3823616c810f86e526d1ed59e7';
var enc = 'M0dvV1hlK0cvT2JrWWJFMGlGN1gyZnJLK0YwWTRTQ2N2N0NxdnIvWnYySHB0VVI2NTZZczNmYlhQVFF5VXFhblQ3WGd4OTBWd01xdlFPT3dLcDdJVUhKeEgyTzREVUY4blMzeXg1Rk9sajg4NU9JbkVOamJoZ215clB4dXROS2daVElQendKenMzV0FwOEQveG93SS93d2hVckpzcTVLKzhDWmhXUEE0Z2dqVU1OK2k0ZVN5bGhIcmt5T1c2bzNxc1UybDdQdzRxUzU3ZG9BS2g5K2d3Q21FME93ZDM0dmRRakU0NWZTK0RRbCtxTXlmLzZPUytpeVBpQUJDYzNoWg==';
var parsed_iv = CryptoJS.SHA256(iv).toString().substring(0, 16);

function decrypt(k, i, v) {
v = new Buffer(v, 'base64');
var decipher = crypto.createDecipheriv('aes-256-cbc', k, i);
decipher.setAutoPadding(false);
var s = decipher.update(v, 'base64', 'utf8');
return Buffer.concat([s,decipher.final('utf8')]);
}
var dec = decrypt(key, parsed_iv, enc);
console.log(dec);
`
I try very much code by search google but it's return binary and i can't convert it into text.
Hope you can help me.
Thanks !

@itmalan

itmalan commented Oct 13, 2017

Copy link
Copy Markdown

It is really a nice post and clearly understandable.

I have an issue in openssl_encrypt(), please help me. I have to do AES-128-ECB with PKCS5 padding. How do I make PKCS5 in openssl_encrypt(). In few online posts it was mentioned openssl_encrypt will do PKCS5/7 padding by default if no option is mentioned.

Thanks in advance

@bladeSk

bladeSk commented Oct 22, 2017

Copy link
Copy Markdown

The IV should be generated for each encrypted message and transmitted with the message. Sending 2 or more messages with the same IV is a serious security flaw. You can use $iv = openssl_random_pseudo_bytes(16) to generate IVs. This shouldn't rely on insecure random number generators such as rand().

Furthermore, you should use actual bytes for key instead of a hex string. Hex string is significantly reducing the possible combinations. $key = hash('sha256', $password, true);

Edit: here's my full code, if you're interested https://stackoverflow.com/a/46872528/388994

@petermuller71

Copy link
Copy Markdown

The problem with open_ssl is that is cannot work with large strings. You get errors...
So you have to split a large string in smaller chuncks..

And as bladeSk mentionend: The IV should be generated for each encrypted message and transmitted with the message.

See working example at (written as static class):
https://gist.github.com/petermuller71/33616d55174d9725fc00a663d30194ba

@test8git

test8git commented Jan 3, 2018

Copy link
Copy Markdown

Thank u so much

@jbvazquez

jbvazquez commented Jan 10, 2018

Copy link
Copy Markdown

Hi is correct if use a secretkey generated with RSA 2048 and as secret_iv a public key?

@twicejr

twicejr commented Jan 29, 2018

Copy link
Copy Markdown

You should always use a random Initialization Vector if you want to protect against replaying attacks. (although the probability of it happening is low)
You can just append or prepend the IV to the output and use it in your decrypt function, it may be exposed publically.

@budhapirthi

Copy link
Copy Markdown

thanks so much for sharing

@Alemalakra

Copy link
Copy Markdown

Nice share fam.

@czubehead

Copy link
Copy Markdown

This is dangerous! IV MUST be random, that is the whole purpose of it. You have just disabled one of the cipher's key mechanisms, well done.

@petemolinero

Copy link
Copy Markdown

@czubehead If it's random, how would you decrypt? How would you modify the code for a more secure encrypt/decrypt?

@spybart

spybart commented Jun 10, 2018

Copy link
Copy Markdown

@petemolinero read the reply by @twicejr and @bladeSk

@Rubinum

Rubinum commented Jul 16, 2018

Copy link
Copy Markdown

This function does two things instead of one and yes functions should do one thing. The name of the function is aweful too! Please don't write such code in that way if you copy that into your projects.

@IwonGunawan

Copy link
Copy Markdown

thank you so much for sharing.
this code help me, very simple and easy to use.

@jagdeepmalhi

Copy link
Copy Markdown

Thanks for sharing.

@legendblogs

Copy link
Copy Markdown

Mcrypt is a replacement for the popular Unix crypt command. the crypt was a file encryption tool that used an algorithm very close to the World War II Enigma cipher. Mcrypt provides the same functionality but uses several modern algorithms such as AES.

class MCrypt {

private $iv = 'abcdef9876541720';
private $key = '1720456789fedcba';

function __construct() {
    
}

/**
 * @param string $str
 * @param bool $isBinary whether to encrypt as binary or not. Default is: false
 * @return string Encrypted data
 */
function encrypt($str, $isBinary = false) {
    $iv = $this->iv;
    $str = $isBinary ? $str : utf8_decode($str);
    $td = mcrypt_module_open('rijndael-128', ' ', 'cbc', $iv);
    mcrypt_generic_init($td, $this->key, $iv);
    $encrypted = mcrypt_generic($td, $str);
    mcrypt_generic_deinit($td);
    mcrypt_module_close($td);
    return $isBinary ? $encrypted : bin2hex($encrypted);
}

/**
 * @param string $code
 * @param bool $isBinary whether to decrypt as binary or not. Default is: false
 * @return string Decrypted data
 */
function decrypt($code, $isBinary = false) {
    $code = $isBinary ? $code : $this->hex2bin($code);
    $iv = $this->iv;
    $td = mcrypt_module_open('rijndael-128', ' ', 'cbc', $iv);
    mcrypt_generic_init($td, $this->key, $iv);
    $decrypted = mdecrypt_generic($td, $code);
    mcrypt_generic_deinit($td);
    mcrypt_module_close($td);
    return $isBinary ? trim($decrypted) : utf8_encode(trim($decrypted));
}

protected function hex2bin($hexdata) {
    $bindata = '';
    for ($i = 0; $i < strlen($hexdata); $i += 2) {
        $bindata .= chr(hexdec(substr($hexdata, $i, 2)));
    }
    return $bindata;
}

}

function encryptkey($key) {
$mcrypt = new MCrypt();
$encrypted = $mcrypt->encrypt($key);
return $encrypted;
}

function decryptkey($key) {
$mcrypt = new MCrypt();
$decrypted = $mcrypt->decrypt($key);
return $decrypted;
}

$value = "Legend Blogs";

echo $value.'
';
echo "Encrypt: ". encryptkey($value).'
';
echo "Decrypt: ". decryptkey(encryptkey($value)).'
';

Complete example at here How do you Encrypt and Decrypt a PHP String

@tonnas

tonnas commented Mar 21, 2019

Copy link
Copy Markdown

Thanks Man !

@josegoyo

josegoyo commented May 15, 2019

Copy link
Copy Markdown

How can I decrypt this in java ?

ghost commented Jul 22, 2019

Copy link
Copy Markdown

Thank you so much, but I have some questions :

  1. Is it safe to use that code in my website when every one know it?
  2. What's the maximum length of the $secret_key and the $secret_iv?
  3. What's the best way to hide that code from everyone?

-Adel Sbeh

@AkshayKhandarkar

Copy link
Copy Markdown

How to add cs5 padding with the encryption?? please, I need to know urgently.

@Josloader3

Copy link
Copy Markdown

great code, thanks a lot

@neutronixx

Copy link
Copy Markdown

Hello thanks for the code, works well, and works with short text strings but how I can encrypt text longer?

@BySkilz0

Copy link
Copy Markdown

Hello from 2021,
Helped me ;)

@LeoDaGuy

Copy link
Copy Markdown

Helped me 👍

@aacassandra

Copy link
Copy Markdown

How can I decrypt this in java ?

simple, you must move to php. haha. just kidding

@GChazaro

GChazaro commented Dec 2, 2024

Copy link
Copy Markdown

Does it work for large amounts of text?

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