Some Strings Won't Decrypt - php

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...

Related

I can encrypt data but cannot decrypt

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;
}

Migration from mcrypt_encrypt() to openssl_encrypt()

I have forced to migrate from PHP 5.6 to 7.0+, everything is fine except the mcrypt_encrypt(), it was deprecated already as stated in php.net.
Here's my code
$json = array(
'Amount' => $amount
);
$data = json_encode($json);
function encrypt($data, $secret)
{
//Generate a key from a hash
$key = md5(utf8_encode($secret), true);
$data2 = utf8_encode($data);
$iv = utf8_encode("jvz8bUAx");
//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', 'cbc');
//Encrypt data
$encData = mcrypt_encrypt('tripledes', $key, $data2, MCRYPT_MODE_CBC, $iv);
return urlencode(base64_encode($encData));
}
I want to replace the deprecated lines with openssl_encrypt.
function encrypt($data, $secret)
{
//Generate a key from a hash
$key = md5(utf8_encode($secret), true);
$data = utf8_encode($data);
$iv = utf8_encode("jvz8bUAx");
$method = 'AES-256-CBC';
$encrypted = openssl_encrypt($data, $method, $key, OPENSSL_RAW_DATA, $iv);
$encrypted = base64_encode($iv . $encrypted);
return $encrypted;
}
Error:
IV passed is only 8 bytes long, cipher expects an IV of precisely 16
bytes, padding with \0
What I am missing?
UPDATE: Adding decryption part
function decrypt($data, $secret)
{
//Generate a key from a hash
$data = urldecode($data);
$iv = utf8_encode("jvz8bUAx");
$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);
$data3 = base64_decode($data);
return $data4 = mcrypt_decrypt('tripledes', $key, $data3, MCRYPT_MODE_CBC, $iv);
}
Updated
So what you are looking for is the des-ede3-cbc Openssl algorithm.
A convenient way to get a list of all your openssl algo's that are on your server is to run:
print_r(openssl_get_cipher_methods(TRUE));
This will generate a list that makes for a good reference.
It looks like there was a padding issue as well. Mcrypt adds padding during the encryption routine and the Openssl does not. So you have to add padding on the encryption side for the Openssl. We also need to force the no_padding in the openssl functions.
These functions should work for you now.
function encryptNew($data, $secret){
//Generate a key from a hash
$key = md5(utf8_encode($secret), true);
$data = utf8_encode($data);
$iv = utf8_encode("jvz8bUAx");
//Take first 8 bytes of $key and append them to the end of $key.
$key .= substr($key, 0, 8); //You key size has to be 192 bit for 3DES.
$method = 'des-ede3-cbc'; //<----Change you method to this...
//Mcrypt adds padding inside the function. Openssl does not. So we have to pad the data.
if (strlen($data) % 8) {
$data = str_pad($data, strlen($data) + 8 - strlen($data) % 8, "\0");
}
$encrypted = openssl_encrypt($data, $method, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); //Force zero padding.
$encrypted = urlencode(base64_encode($encrypted)); //Added the urlencode.....
return $encrypted;
}
function decryptNew($data, $secret){
//$data = base64_decode(urldecode($data));//<--If you have raw data coming in this needs to be commented out.
$iv = utf8_encode("jvz8bUAx");
$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);
$method = 'des-ede3-cbc';
return openssl_decrypt($data, $method, $key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING, $iv); //Force zero padding.
}
Hope this helps.

SHA 1 hash_hmac wrong

I have a big problem with hash_hmac
function
function hmac($key, $data){
$blocksize = 64;
$hashfunc = 'sha1';
if (strlen($key) > $blocksize)
$key = pack('H*', $hashfunc($key));
$key = str_pad($key, $blocksize, chr(0x00));
$ipad = str_repeat(chr(0x36), $blocksize);
$opad = str_repeat(chr(0x5c), $blocksize);
$hmac = pack('H*', $hashfunc(($key ^ $opad) . pack('H*', $hashfunc(($key ^ $ipad) . $data))));
return bin2hex($hmac);
}
example is:
<?php
echo hmac('111111', '222222');//=1558ab6c5ab2b0d1cd129b9ad11527cf33486705
but my
$jeden = 111111;
$dwa =222222;
$hashWiadomosci = hash_hmac('sha1', $jeden, $dwa);
is: 22f91d281349bb3081d3cec9f906572eec5c55b2
how i do wrong?
You have your input variables in the wrong order. If you look at the example from the comment you got this from; you can see that it is hmacsha1($key, $data) and not hmacsha1($data, $key) like you are using it and how hash_hmac($algorithm, $data, $key) works.
echo hash_hmac('sha1', '111111', '222222'); // 22f91d2813...
echo hmacsha1('111111', '222222'); // 1558ab6c5a...
echo hash_hmac('sha1', '111111', '222222'); // 22f91d2813...
echo hmacsha1('222222', '111111'); // 22f91d2813...

PHP Encrypt/Decrypt with TripleDes, PKCS7, and ECB

I've got my encryption function working properly however I cannot figure out how to get the decrypt function to give proper output.
Here is my encrypt function:
function Encrypt($data, $secret)
{
//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);
}
Here is my decrypt function:
function Decrypt($data, $secret)
{
$text = base64_decode($data);
$data = mcrypt_decrypt('tripledes', $secret, $text, 'ecb');
$block = mcrypt_get_block_size('tripledes', 'ecb');
$pad = ord($data[($len = strlen($data)) - 1]);
return substr($data, 0, strlen($data) - $pad);
}
Right now I am using a key of test and I'm trying to encrypt 1234567. I get the base64 output from encryption I'm looking for, but when I go to decrypt it returns nothing (a blank area).
I'm not very well versed in encryption/decryption so any help is much appreciated!!
Thanks for anyone who took a look at my problem. I think I have solved it and here is my full solution. Hopefully it helps out someone else who is having a similar issue:
function Encrypt($data, $secret)
{
//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);
}
And here is the new decrypt function.
function Decrypt($data, $secret)
{
//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);
}
I had to add the same code for generating the key in the correct format before I ran the mycrypt_decrypt function.

mcrypt_encrypt fails to initialise

I am trying to encrypt some data in PHP using the Rijndael cipher in CBC mode with a 256bit key but for some reason I get the following error message:
mcrypt_encrypt() Module initialization failed
My code:
$hashKey = hash('sha256',$key);
$iv = hash('sha256',$hashKey);
// ------Cipher-------------key-------------Data-------------Mode---------IV--
$encryptedQuestion = base64_encode(mcrypt_encrypt('MCRYPT_RIJNDAEL_256', $hashKey , $_POST['question'], MCRYPT_MODE_CBC, $iv));
Can anyone see whats wrong with this?
There are a few issues with the code that I can spot:
Your $iv should not be dependent on $hashKey; rather, you should create it separately using mcrypt_create_iv().
Your $hashKey should be binary rather than textual.
MCRYPT_RIJNDAEL_256 is a constant, it should not be passed as a string.
The following code is more verbose than yours, but it should give you an insight in the steps required to encrypt something:
$crypto = mcrypt_module_open(MCRYPT_RIJNDAEL_256, '', MCRYPT_MODE_CBC, '');
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($crypto), MCRYPT_DEV_URANDOM);
$hkey = hash('sha256', $key, true);
mcrypt_generic_init($handle, $hkey, $iv);
$enc_question = mcrypt_generic($handle, $_POST['question']);
mcrypt_generic_deinit($handle);
mcrypt_module_close($handle);
I've also left out any error checks.
I got a similar error. I assigned the constants to a variable and passed the variable and that was the cause of the error.
This failed for me
>
return new encKey($cipher_name, $mode, $value);
Now this works
>
return new encKey(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB, $value);
In php 5.6 try mcrypt_ecb to overcome the invalid key issue
$choice ="2";
$key = "1234";
$key = hash("sha512", $key, TRUE);
for ($x = 0; $x < 8; $x++) {
$key = $key . substr($key, $x, 1);
}
$msg = "pato";
echo("key is".$key." \n");
if ($msg == ''){
die("Please enter a text to encrypt! ");
}
if ($key == ''){
die("Please enter a key! ");
}
function pkcs5_pad($text, $blocksize) {
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
}
function pkcs_pad($text, $blocksize) {
//$pad = $blocksize - (strlen($text) % $blocksize);
$tes=substr($text,0,$blocksize) ;
return $tes;
}
function encryptnow( $thekey, $themsg)
{
$padded = pkcs5_pad($themsg, mcrypt_get_block_size(MCRYPT_3DES, MCRYPT_MODE_CBC));
echo("padded".$padded."\n");
$keypad = pkcs_pad($thekey, mcrypt_get_key_size(MCRYPT_3DES, MCRYPT_MODE_CBC));
$i;
//$iv=pkcs5_pad($i, mcrypt_get_block_size(MCRYPT_3DES, MCRYPT_MODE_CBC));
//$iv = mcrypt_create_iv(8, MCRYPT_DEV_RANDOM);
// echo("padded".$keypad."\n");
$encrypted = base64_encode(mcrypt_ecb(MCRYPT_3DES, $keypad, $padded, MCRYPT_MODE_CBC));
echo "<html><hr size='2' ></html>";
echo "<P><P><b>Plain Text : </b>";
echo($themsg);
echo "<p><b>Cipher Text : </b> ";
echo "$encrypted";
die();
}
if ($choice == '2'){
encryptnow($key, $msg);
}

Categories