I created this question to share a PHP version (based on the version at CryptoJS extra parameter in AES Encrypt. How to replicate with PHP?) of a script that has the same return as CryptoJS, this version in PHP that no longer uses the mbcrypt methods (which are deprecated after PHP 7.1.0)
<?php
class CryptoJS {
const ALGO_METHOD = 'AES-256-CBC';
public static function encrypt(string $plaintext, string $password) {
$salt = substr(md5(mt_rand(), true), 8);
$block = openssl_cipher_iv_length(self::ALGO_METHOD);
$pad = $block - (strlen($plaintext) % $block);
$data = $plaintext . str_repeat(chr($pad), $pad);
$iv_len = openssl_cipher_iv_length(self::ALGO_METHOD);
$key_len = $iv_len * 2;
$total_len = $key_len + $iv_len;
$salted = '';
$dx = '';
while (strlen($salted) < $total_len) {
$dx = md5($dx . $password . $salt, true);
$salted .= $dx;
}
$key = substr($salted, 0, $key_len);
$iv = substr($salted, $key_len, $iv_len);
$encrypted_data = openssl_encrypt($data, self::ALGO_METHOD, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv);
return base64_encode('Salted__' . $salt . $encrypted_data);
}
public static function decrypt(string $edata, string $pass) {
$data = base64_decode($edata);
$salt = substr($data, 8, 8);
$ct = substr($data, 16);
$rounds = 3;
$data00 = $pass . $salt;
$md5_hash = array();
$md5_hash[0] = md5($data00, true);
$result = $md5_hash[0];
for ($i = 1; $i < $rounds; $i++) {
$md5_hash[$i] = md5($md5_hash[$i - 1] . $data00, true);
$result .= $md5_hash[$i];
}
$key = substr($result, 0, 32);
$iv = substr($result, 32, 16);
return openssl_decrypt($ct, self::ALGO_METHOD, $key, true, $iv);
}
}
$pass = $text = '{TextAndPass}';
$encrypted = CryptoJS::encrypt($text, $pass);
$decrypted = CryptoJS::decrypt($encrypted, $pass);
var_dump($encrypted, $decrypted);
Related
I'm trying to make a program where people can chat and I want to encrypt the messages that are being sent. I have 2 scripts for this, one is sendtext.php and another getchat.php.
So my question is how can I encrypt the text that's being sent in one file and then decrypt the messages that will be sent back which is in another file.
So far I have the encryption working but I dont know how to decrypt in the other file.
Also if you know a more secure way of doing this it would be appreciated.
sendtext.php
$username = $_POST["name"];
$text = $_POST["message"];
$key = openssl_random_pseudo_bytes(32, $cstrong);
$cipher = "aes-128-gcm";
if (in_array($cipher, openssl_get_cipher_methods()))
{
$ivlen = openssl_cipher_iv_length($cipher);
$iv = openssl_random_pseudo_bytes($ivlen);
$ciphertext = openssl_encrypt($text, $cipher, $key, $options=0, $iv, $tag);
echo "Encrytped: " . $ciphertext;
//store $cipher, $iv, and $tag for decryption later
//$original_text = openssl_decrypt($ciphertext, $cipher, $key, $options=0, $iv, $tag);
//echo $original_text."\n";
}
//Add text to the table
$inserttextquery = "INSERT INTO ".$username." (username, message)
VALUES ('$username', '$ciphertext');";
mysqli_query($con, $inserttextquery) or die("#: send text failed");
getchat.php
$username = $_POST["name"];
$sql = "SELECT username, message FROM ".$username."";
$result = $con->query($sql);
if ($result->num_rows > 0)
{
// output data of each row
while($row = $result->fetch_assoc()) {
echo $row["username"] . "\t" . $row["message"] . "\t";
}
}
I wrote this encryption/decryption class awhile ago:
<?php
class Cryptography
{
private static $secret_key = 'gsdgsg423b523b5432bjbjm24vbjn2hv';
const CIPHER_16 = 'AES-128-CBC';
const CIPHER_32 = 'AES-256-CBC';
public static function encrypt($str, $cl = 32)
{
return static::encyptedDecypted('encrypt', $str, $cl);
}
public static function decrypt($str, $cl = 32)
{
return static::encyptedDecypted('decrypt', $str, $cl);
}
public static function encyptedDecypted($action, $str, $cl)
{
$cl = (int) $cl;
if ($cl === 16) {
$cipher = static::CIPHER_16;
$length = 16;
} elseif ($cl === 32) {
$cipher = static::CIPHER_32;
$length = 32;
} else {
throw new Exception('Error Processing Request', 1);
}
$iv = $iv = substr(hash('sha256', static:: $secret_key), 0, 16);
$key = hash('sha512', static::$secret_key);
if ($action == 'encrypt') {
$output = openssl_encrypt($str, $cipher, $key, 0, $iv);
$output = base64_encode($output);
$output = static::securesalts($length).$output.static::securesalts($length);
} elseif ($action == 'decrypt') {
$str = $text = substr($str, $length, -$length);
$output = openssl_decrypt(base64_decode($str), $cipher, $key, 0, $iv);
}
return $output;
}
private static function securesalts($length)
{
if (is_int($length) && $length >= 5) {
$chars = array_merge(range(0, 9), range('a', 'z'), range('A', 'Z'));
$stringlength = count($chars); //Used Count because its array now
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $chars[rand(0, $stringlength - 1)];
}
return $randomString;
} else {
return false;
}
}
}
Use it like this:
$str = "Simple String";
//for encryption
$encrypted = Cryptography::encrypt($str);
//for decryption
$decrypted = Cryptography::decrypt($encrypted);
Don't forget to change the $secret_key ;)
I used AES for encrypt the post parameters that send from java to server with volley. so I used below's class in my server for decrypt the post parammeters .
<?php
class MCrypt {
private $hex_iv = '31323334353637383930616263646566'; # converted Java byte code in to HEX and placed it here
private $key = '0FDOUZ.Qz'; #Same as in JAVA
function __construct() {
$this->key = hash('sha256', $this->key, true);
//echo $this->key.'<br/>';
}
function encrypt($str) {
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
mcrypt_generic_init($td, $this->key, $this->hexToStr($this->hex_iv));
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$pad = $block - (strlen($str) % $block);
$str .= str_repeat(chr($pad), $pad);
$encrypted = mcrypt_generic($td, $str);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return base64_encode($encrypted);
}
function decrypt($code) {
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
mcrypt_generic_init($td, $this->key, $this->hexToStr($this->hex_iv));
$str = mdecrypt_generic($td, base64_decode($code));
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $this->strippadding($str);
}
/*
For PKCS7 padding
*/
private function addpadding($string, $blocksize = 16) {
$len = strlen($string);
$pad = $blocksize - ($len % $blocksize);
$string .= str_repeat(chr($pad), $pad);
return $string;
}
private function strippadding($string) {
$slast = ord(substr($string, -1));
$slastc = chr($slast);
$pcheck = substr($string, -$slast);
if (preg_match("/$slastc{" . $slast . "}/", $string)) {
$string = substr($string, 0, strlen($string) - $slast);
return $string;
} else {
return false;
}
}
function hexToStr($hex)
{
$string='';
for ($i=0; $i < strlen($hex)-1; $i+=2)
{
$string .= chr(hexdec($hex[$i].$hex[$i+1]));
}
return $string;
}
}
?>
Also I used below's code in newuser.php file .
<?php
.....
//decrypt
$encryption = new MCrypt();
$phone= $encryption->decrypt($phoneenc);
$password= $encryption->decrypt($passwordenc);
$serialdivice= $encryption->decrypt($serialdiviceenc);
$sequretyQustion= $encryption->decrypt($sequretyQustionenc);
$sequretyAnsewr= $encryption->decrypt($sequretyAnsewrenc);
.... ?>
Before Update php to php7.2 my code worked correctly . But for now It get error for decrypt method when I updated php . so How can i fix it?
I used openssl for both java and php .It's working correctly now.
I can successfully encrypt passed data but sadly cannot decrypt it. What is wrong with my decrypt() function? Maybe it is something with my Initialization Vector(iv). Here is my code:
function pad($data, $size) {
$length = $size - strlen($data) % $size;
return $data . str_repeat(chr($length), $length);
}
function unpad($data) {
return substr($data, 0, -ord($data[strlen($data) - 1]));
}
//CORRECT ENCRYPTION METHOD
function encrypt($data) {
$key = "SiadajerSiadajer";
$iv_size = 16;
$iv = openssl_random_pseudo_bytes($iv_size, $strong);
$encryptedData = openssl_encrypt(pad($data, 16), 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
$joinedData = hex2bin(bin2hex($iv).bin2hex($encryptedData));
$encodedJoinedData = base64_encode($joinedData);
return $encodedJoinedData;
}
//WRONG DECRYPTION FUNCTION
function decrypt($encodedJoinedData){
$key = "SiadajerSiadajer";
$DecodedData = base64_decode($encodedJoinedData);
$size = strlen($DecodedData);
$cipheredsize = $size - 16;
$iv = substr($DecodedData, 0, 16);
$halfDecryptedData = substr($DecodedData, 16, $size);
$decryptedData = openssl_decrypt(unpad($halfDecryptedData, 16), 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
return $decryptedData;
}
$test = encrypt("sssss");
print $test;
$test2 = decrypt($test);
print $test2;
In the encrypt-method replace the line
$joinedData = hex2bin(bin2hex($iv).bin2hex($encryptedData));
with
$joinedData = $iv.$encryptedData;
because the conversions in the previous expression are unnecessary. This replacement doesn't change the result.
A possible solution for the decryption-part could be:
function decrypt($encodedJoinedData) {
$joinedData = base64_decode($encodedJoinedData);
$iv = substr($joinedData, 0, 16);
$encryptedData = substr($joinedData, 16);
$key = "SiadajerSiadajer";
$decryptedData = openssl_decrypt($encryptedData, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
$unpaddedData = unpad($decryptedData);
return $unpaddedData;
}
$data = 'Durgadevi'.date('Y-m-d H:m:s');
$b = encrypt($data);
echo '<b>actual data: </b>'.$data.'<br><b> encrypted code: </b>'.$b;
function encrypt($string)
{
$encrypt_method = "AES-256-CBC";
$secret_key = '123456';
$secret_iv = 'This is my secret iv';
$key = hash('sha256',$secret_key);
$iv = substr(hash('sha256',$secret_iv),0,16);
$output = openssl_encrypt($string,$encrypt_method,$key,0,$iv);
return $output;
}
After executing encrypt function
OUTPUT:
actual data: Durgadevi11:07:40
encrypted code: Fxf6Q73Fs5byu6e2R0nTwG01n4vsoBAyfefSY5HBSWM=
$data = 'Fxf6Q73Fs5byu6e2R0nTwG01n4vsoBAyfefSY5HBSWM=';
$b = decrypt($data);
echo '<b> actual data: </b>'.$data.'<br><b> decrypted code: </b>'.$b;
function decrypt($string)
{
$encrypt_method = "AES-256-CBC";
$secret_key = '123456';
$secret_iv = 'This is my secret iv';
$key = hash('sha256',$secret_key);
$iv = substr(hash('sha256',$secret_iv),0,16);
$output = openssl_decrypt($string,$encrypt_method,$key,0,$iv);
return $output;
}
After executing decrypt function
OUTPUT:
actual data: Fxf6Q73Fs5byu6e2R0nTwG01n4vsoBAyfefSY5HBSWM=
decrypted code: Durgadevi11:07:40
You can use below function for encryption and decryption.
function encryptDecrypt($action, $data) {
$output = false;
$encrypt_method = "AES-256-CBC";
$secret_key ="g3hR0m9FY1r+9ZXLdriXI4U6AxsYqlbISe8Qne9DuJU9R1AlvsV1GWQMQhP0NcvvtnvSB1AoIBAQD8zQp+VhgSH";
$secret_iv = "xaghJBqlqQPkox2djChy3+3tmEPZJpypp4Euy2sDLSgyP+nsecrkP18bfl2i+ChPAoIBAQC3FijLZr74H0m9oGj0hPAlfcAh5bTMvAF4993M8BjncApCzKMOK3CLT+278dquihNCyrbK6/FjDMw9sGl5kctenaOVcvtdupMWtX9U9KmH8G1XCX/Xr/umpgAxjh+l69v4lrDRln48/gT9zfdKjZ5OiuW+M+gbNL6qGAM";
$key = hash('sha256', $secret_key);
$iv = substr(hash('sha256', $secret_iv), 0, 16);
if ($action == 'encrypt') {
$output = openssl_encrypt($data, $encrypt_method, $key, 0, $iv);
$output = base64_encode($output);
} else if ($action == 'decrypt') {
$output = openssl_decrypt(base64_decode($data), $encrypt_method, $key, 0, $iv);
}
return $output;
}
//Call as below
$string = 'Durgadevi'.date('Y-m-d H:m:s');
echo $encString = encryptDecrypt('encrypt', $string);
echo "<br/>";
echo encryptDecrypt('decrypt', $encString);
I have a function to encrypt and decrypt a string with a salt/password, but there's an issue, I have no problem encrypting any string, but with decrpyting it has a problem decrypting some strings...
For example it will decrypt "Hello World", but not "Login" or "RedeemToken"... The code i'm using is below with some outputs and debugging stuff:
function encrypt($data)
{
$secret = "FUSIONIDISTOPNOTCHCODEDBYMELTYNET";
//Generate a key from a hash
$key = md5(utf8_encode($secret), true);
//Take first 8 bytes of $key and append them to the end of $key.
$key .= substr($key, 0, 8);
//Pad for PKCS7
$blockSize = mcrypt_get_block_size('tripledes', 'ecb');
$len = strlen($data);
$pad = $blockSize - ($len % $blockSize);
$data .= str_repeat(chr($pad), $pad);
//Encrypt data
$encData = mcrypt_encrypt('tripledes', $key, $data, 'ecb');
return base64_encode($encData);
}
function decrypt($data)
{
$secret = "FUSIONIDISTOPNOTCHCODEDBYMELTYNET";
//Generate a key from a hash
$key = md5(utf8_encode($secret), true);
//Take first 8 bytes of $key and append them to the end of $key.
$key .= substr($key, 0, 8);
$data = base64_decode($data);
$data = mcrypt_decrypt('tripledes', $key, $data, 'ecb');
$block = mcrypt_get_block_size('tripledes', 'ecb');
$len = strlen($data);
$pad = ord($data[$len-1]);
return substr($data, 0, strlen($data) - $pad);
}
Also the functions above are used like this:
echo encrypt($string);
echo decrypt($string);
Example of some strings that encrypt, but will not encrypt:
Login - Doesn't Decrypt
RedeemToken - Doesn't Decrypt
Blacklist - Decrypt Works
Email - Decrypt Works
If anyone can point out the issue or help, please let me know, thanks!
HERE IS MY CODE:
USE - "http://example.com/test.php?st=xeJuD3+A0Po="
<?php
$string123 = mysql_escape_string($_GET["st"]);
echo decrypt($string123);
function encrypt($data)
{
$secret = "FUSIONIDISTOPNOTCHCODEDBYMELTYNET";
//Generate a key from a hash
$key = md5(utf8_encode($secret), true);
//Take first 8 bytes of $key and append them to the end of $key.
$key .= substr($key, 0, 8);
//Pad for PKCS7
$blockSize = mcrypt_get_block_size('tripledes', 'ecb');
$len = strlen($data);
$pad = $blockSize - ($len % $blockSize);
$data .= str_repeat(chr($pad), $pad);
//Encrypt data
$encData = mcrypt_encrypt('tripledes', $key, $data, 'ecb');
return base64_encode($encData);
}
function decrypt($data)
{
$secret = "FUSIONIDISTOPNOTCHCODEDBYMELTYNET";
//Generate a key from a hash
$key = md5(utf8_encode($secret), true);
//Take first 8 bytes of $key and append them to the end of $key.
$key .= substr($key, 0, 8);
$data = base64_decode($data);
$data = mcrypt_decrypt('tripledes', $key, $data, 'ecb');
$block = mcrypt_get_block_size('tripledes', 'ecb');
$len = strlen($data);
$pad = ord($data[$len-1]);
return substr($data, 0, strlen($data) - $pad);
}
?>
Found ;)
In your URL, use http://example.com/test.php?st=xeJuD3%2BA0Po%3D as =+ and other char are not allowed tu be used in URL.
Take a look at http://php.net/manual/fr/function.rawurlencode.php to craft right URL from your base64 encrypted data
If you can't change the URL before it hit PHP, you'll have to change back the space in + :
$_GET['st'] = str_replace(' ', '+', $_GET['st']);
And BTW, remove the $string123 = mysql_escape_string($_GET["st"]); mysql_ is for mysql, nothing else, it's not a magic spell you cast everywhere. the only thing it does is change ' to \' and it wont help you anywhere; even in MySQL it's now depreciated and you need to use PDO or mysqli
for this :
<?php
function encrypt($data)
{
$secret = "FUSIONIDISTOPNOTCHCODEDBYMELTYNET";
//Generate a key from a hash
$key = md5(utf8_encode($secret), true);
//Take first 8 bytes of $key and append them to the end of $key.
$key .= substr($key, 0, 8);
//Pad for PKCS7
$blockSize = mcrypt_get_block_size('tripledes', 'ecb');
$len = strlen($data);
$pad = $blockSize - ($len % $blockSize);
$data .= str_repeat(chr($pad), $pad);
//Encrypt data
$encData = mcrypt_encrypt('tripledes', $key, $data, 'ecb');
return base64_encode($encData);
}
function decrypt($data)
{
$secret = "FUSIONIDISTOPNOTCHCODEDBYMELTYNET";
//Generate a key from a hash
$key = md5(utf8_encode($secret), true);
//Take first 8 bytes of $key and append them to the end of $key.
$key .= substr($key, 0, 8);
$data = base64_decode($data);
$data = mcrypt_decrypt('tripledes', $key, $data, 'ecb');
$len = strlen($data);
$pad = ord($data[$len-1]);
return substr($data, 0, strlen($data) - $pad);
}
echo "'". ($a = encrypt('Email'))."'<br>\n";
echo "'".decrypt($a)."'<br>\n";
echo "'".decrypt('AA/PpTmKWjY=')."'<br>\n";
echo "'".($e= encrypt('Login'))."'<br>\n";
echo "'".decrypt($e)."'<br>\n";
echo "'".decrypt('xeJuD3+A0Po=')."'<br>\n";
I get :
'AA/PpTmKWjY='
'Email'
'Email'
'xeJuD3+A0Po='
'Login'
'Login'
So, for me it work fine...