mcrypt_decrypt wrong output after using encrypted data php - php

I have a small problem with php mcrypt_decrypt function. Firstly, I use a 16-byte string, and encrypt it using mcrypt_encrypt; then, I use base64_encode, and put the output to mcrypt_decrypt, in order to get the initial string.
But the output is not what's expected. I checked that my base64 decoded string input for decoding is the exact output produced by mcrypt_decrypt. Here is my code:
//encrypt
$str="KKQT9W4st7vmdkps";
$key="43625A8C1E4330BDF84DDEE3DD105037";
$block = mcrypt_get_block_size('rijndael_128', 'ecb');
$passcrypt=mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $str, MCRYPT_MODE_ECB);
echo $passcrypt;
That outputs PTfZ6Ephh8LTxXL4In33Og==. The decryption script is the following:
//decrypt
$str='PTfZ6Ephh8LTxXL4In33Og==';
$key='43625A8C1E4330BDF84DDEE3DD105037';
$str = base64_decode($str);
$str = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key,
$str, MCRYPT_MODE_ECB,''),"\0");
$block = mcrypt_get_block_size('rijndael_128', 'ecb');
echo $str;
And the output is not KKQT9W4st7vmdkps, but -nγ kk7Ζn’T instead. Any ideas? I'm using XAMPP and Apache server.

Thx guys for the feedback it was a silly mistake that i made...actually 'PTfZ6Ephh8LTxXL4In33Og==' was wrong in the decrypt function cause "I" was "l" in the end...so the decryption was not correct...but it was not my fault either since I was getting this string from a QR CODE scanner and both "I" and "l" are displayed the same...

For encryption, you need to:
1) Create an encryption resource
$str = "KKQT9W4st7vmdkps";
$key = "43625A8C1E4330BDF84DDEE3DD105037";
$r = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '',MCRYPT_MODE_ECB, '');
2) Randomly create encryption vector based on the size of $r
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($r),MCRYPT_RAND);
3) Initiliazing module using the resource,key and string vector
mcrypt_generic_init($r,$key,$iv);
4) Encrypt data/string using resource $r
$encrypted = mcrypt_generic($r,$str);
5) Encode it using base64_encode
$encoded = base64_encode($encrypted);
if(!mcrypt_generic_deinit($r) || !mcrypt_module_close($r))
$encoded = false;
6) Echoing it
echo 'Encrypted: '.$encoded;
For decryption, it's like a reverse process of encrypt
//Using the same enrypted string
$decoded = (string) base64_decode(trim($encoded));
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '',MCRYPT_MODE_ECB, '');
$ivs = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
mcrypt_generic_init($td,$key, $ivs);
$decoded = (string) trim(mdecrypt_generic($td, $decoded));
if(!mcrypt_generic_deinit($td) || !mcrypt_module_close($td))
$decoded = false;
Echoing it
echo 'Decrypted: '. $decoded;
Hope this helps. More info here.

Related

Passing base64 to URL in PHP to decode with OpenSSL

I'm trying to pass an argument via URL. This argument is base64.
https://site/file?base=+EOOJZIWLfQwoiVT6rfDbj3sr9vabuzX84bcT38u9hQSW3d/ErsE9E2OlXRvc88x
To decrypt it in PHP file with OpenSSL. When I send it, in PHP file it becomes
"EOOJZIWLfQwoiVT6rfDbj3sr9vabuzX84bcT38u9hQSW3d/ErsE9E2OlXRvc88x"
It escapes " + " in base64.
So OpenSSL can't decrypt it, because it gets the wrong base64. I tried urlencode, but it escapes " / " to " %2f" so same here.
This is my code:
$user = urlencode($_GET['base64']); // user
$key = ('12345678901234567890123456789012');
$iv = ('1234567890123456');
$field_data = htmlspecialchars($user);
//$e = urldecode($field_data);
$output = openssl_decrypt($field_data, 'AES-256-CBC', $key, 0, $iv);
Solved by insted of encode with base64 do it with base64-url encode and decode it in php by base64 decode thats make it return to normal base64 .. then pass it to openssl
$user = $_GET['x']; // user
function base64url_encode($data) {
return rtrim(strtr($data, '+/', '-_'), '=');
}
function base64_url_decode($input) {
return strtr($input, '._-', '+/+');
}
$last = base64_url_decode ( $user);
$key = ('12345678901234567890123456789012');
$iv = ('1234567890123456');
$output = openssl_decrypt($last, 'AES-256-CBC', $key, 0, $iv);
where url passed is
https://site/file?base=-EOOJZIWLfQwoiVT6rfDbj3sr9vabuzX84bcT38u9hQSW3d_ErsE9E2OlXRvc88x
i used client side c++ for encrypt aes and base64 url

encrypt and decrypt with diacrits

I have these code for encrypt and decrypt.
It works good for text (for example: "This is a text"), which is withnout diacritics (that means without : ěščřžýáíéúů).
But I need encrypt and decrypt text with this special letters (with : ěščřžýáíéúů).
Can somebody help me, please?
Thank so much for every answer and help.
Have a nice day. M.
define ("ENCRYPTION_KEY", "QaY7e4d1c");
$string= "This is a text"; // -> this work alright
//$string= "áýžřčšě"; I NEED THIS TEXT ENCRYPT AND DECRTYPT
echo $encrypted = encrypt($string, ENCRYPTION_KEY);
echo "<br />";
echo $decrypted = decrypt($encrypted, ENCRYPTION_KEY);
function encrypt ($pure_string,$encryption_key)
{
$iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH,MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size,MCRYPT_RAND);
$encrypted_string = mcrypt_encrypt(MCRYPT_BLOWFISH,$encryption_key,utf8_encode($pure_string),MCRYPT_MODE_ECB,$iv);
return $encrypted_string;
}
function decrypt ($encrypted_string,$encryption_key)
{
$iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH,MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size,MCRYPT_RAND);
$decrypted_string = mcrypt_decrypt(MCRYPT_BLOWFISH,$encryption_key,$encrypted_string,MCRYPT_MODE_ECB ,$iv);
return $decrypted_string;
}
You're calling utf8_encode in your encryption function, but not calling utf8_decode when you decrypt, so your functions as they stand don't complement each other.
I'd recommend removing the call to utf8_encode entirely. mcrypt_encrypt doesn't care what encoding your string uses, so whatever you pass in will be what you get back out. Your script works fine for me if I remove it:
$encrypted_string = mcrypt_encrypt(MCRYPT_BLOWFISH, $encryption_key, $pure_string, MCRYPT_MODE_ECB, $iv);
I'd also suggest reading this: https://paragonie.com/blog/2015/05/if-you-re-typing-word-mcrypt-into-your-code-you-re-doing-it-wrong

Impossible decrypt json encrypted with php mcrypt : RIJNDAEL 128

I'm trying to send an encrypted json file to the mobile app.
I'm using RIJNDAEL_128 with MODE_CBC using PHP Mcrypt module; all works perfect on Server A ( Hostmetro provider ) but when i try the same script to Server B ( Hostgator provider ) the data encrypted can't be decrypted from mobile app.
I'm using the same key and the same IV ( the IV is set to 'zero' : \0 ).
I have checked the mcrypt version and it is the same on server A and B, only PHP version is different.
I test the script on my localhost and the json encrypt is changed again.
All my test say that if i try to encrypt a string like 'text' the result is the same everywhere, but if i try with a json the result is very different : where is the problem?
Thanks.
Update:
The code of the encrypt function is:
$str = $decrypted;
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
if (($pad = $block - (strlen($str) % $block)) < $block)
{
$str .= str_repeat(chr($pad), $pad);
}
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$iv = ''; for($i=0;$i<$iv_size;$i++){ $iv .= "\0";}
return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $this->the_key, $str, MCRYPT_MODE_CBC, $iv));
This is the code of the decrypt funciton:
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$iv = ''; for($i=0;$i<$iv_size;$i++){ $iv .= "\0";}
$str = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $this->the_key, base64_decode($encrypted), MCRYPT_MODE_CBC, $iv);
# Strip PKCS7 padding.
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$pad = ord($str[($len = strlen($str)) - 1]);
if ($pad && $pad < $block && preg_match(
'/' . chr($pad) . '{' . $pad . '}$/', $str))
{
return substr($str, 0, strlen($str) - $pad);
}
return $str;
UPDATE 08/12/2014
I have tested the generation of encrypted file and my localhost and my first server ( Hostmetro ) give me a valid file; only Hostgator create a "corrupted" file that can't be decrypted.
Try a base64_encode / decode before encryption / decription ..
Ok, i have found the problem: the problem is that when json_encode() try to encode an multidimensional array and not all the contents are cast to string when you encrypt this json object it can be decrypted by PHP in other server or the same but not by the mobile app.
THE SOLUTION
The solution is cast data into String, transform the array with json_encode(), encrypt the json with mcrypt : all is working now.

3des in php - cannot get good key/string

I need to decode a 3des string in a php and I have no experience in decripting so far...
First step is: get the key and the set of strings to decode - I have that already.
I have this information about algorythm:
type: CBC,
padding - PKCS5,
initialization vector (iv?) - array of eight zeros
I try this way:
// very simple ASCII key and IV
$key = "passwordDR0wSS#P6660juht";
$iv = "password";
//$iv = array('0','0','0','0','0','0','0','0');
//$iv = "00000000";
$cipher = mcrypt_module_open(MCRYPT_3DES, '', 'cbc', '');
//$iv = mcrypt_enc_get_iv_size($cipher);
// DECRYPTING
echo "<b>String to decrypt:</b><br />51196a80db5c51b8523220383de600fd116a947e00500d6b9101ed820d29f198c705000791c07ecc1e090213c688a4c7a421eae9c534b5eff91794ee079b15ecb862a22581c246e15333179302a7664d4be2e2384dc49dace30eba36546793be<br /><br />";
echo "<b>Decrypted 3des string:</b><br /> ".SimpleTripleDesDecrypt('51196a80db5c51b8523220383de600fd116a947e00500d6b9101ed820d29f198c705000791c07ecc1e090213c688a4c7a421eae9c534b5eff91794ee079b15ecb862a22581c246e15333179302a7664d4be2e2384dc49dace30eba36546793be')."<br />";
function SimpleTripleDesDecrypt($buffer) {
global $key, $iv, $cipher;
mcrypt_generic_init($cipher, $key, $iv);
$result = rtrim(mdecrypt_generic($cipher, hex2bin($buffer)), "\0");
mcrypt_generic_deinit($cipher);
return $result;
}
function hex2bin($data)
{
$len = strlen($data);
return pack("H" . $len, $data);
}
At the beginnig you see example data, and on this data code works fine. Problem starts when I try to use my own data I get from database by SOAP webservice. I see this error:
Warning: pack() [function.pack]: Type H: illegal hex digit in....
I get this despite making attempts with different types of codings in the script. Script file itself is in ANCI.
Also: as you see in comments I also have made some experiments with IV but it doesn't make sense without dealing with first problem I gues.
Another thing is padding == PKCS5. Do I need to use it, and how should I do it in my case?
I would really appreciate help with this.
Ok, I have found a solution based mostly on this post: PHP Equivalent for Java Triple DES encryption/decryption - thanx guys and +1.
$iv = array('0','0','0','0','0','0','0','0');
echo #decryptText($temp->patient->firstName, $deszyfrator->return->rawDESKey, $iv);
echo #decryptText($temp->patient->surname, $deszyfrator->return->rawDESKey, $iv);
function decryptText($encryptText, $key, $iv) {
$cipherText = base64_decode($encryptText);
$res = mcrypt_decrypt("tripledes", $key, $cipherText, "cbc", $iv);
$resUnpadded = pkcs5_unpad($res);
return $resUnpadded;
}
function pkcs5_unpad($text)
{
$pad = ord($text{strlen($text)-1});
if ($pad > strlen($text)) return false;
if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) return false;
return substr($text, 0, -1 * $pad);
}
However I get a warning (hidden with # now). "Iv should have the same lenght as block size" - I tried all combinations I could figure out and I can't get rid of it. Any idea people?
Edit: secondary problem fixed to. This kode will fix the iv:
$iv_size=mcrypt_get_iv_size("tripledes","cbc");
$iv = str_repeat("\0", $iv_size); //iv size for 3des is 8

Problem with serialize/unserialize and mcrypt when doing Signed Cookies

I'm working with a friend to get signed cookies on a website but I'm having a lot of problems when trying to encrypt it with mcrypt and MCRYPT_RIJNDAEL_256. I've the cookies working fine, so the problem is only when encrypting/decrypting the value of the cookie.
Here is the error is showed when trying to decrypt the cookie:
Notice: unserialize(): Error at offset 0 of 93 bytes in /var/samba/www/xxx/src/data/include/yyy/Cookie.php on line 94
This exact line corresponds to:
$this->_cookie["value"] = unserialize(mdecrypt_generic($tv, $cookie_value));
And here is how I manage to encrypt / decrypt.
First, send cookie.
$tv = mcrypt_module_open(MCRYPT_RIJNDAEL_256, null, "ctr", null);
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($tv), MCRYPT_RAND);
mcrypt_generic_init($tv, "t3stp4ssw0rd", $iv);
$this->_cookie["value"] = base64_encode(mcrypt_generic($tv, serialize($this->_cookie["value"])));
mcrypt_generic_deinit($tv);
mcrypt_module_close($tv);
setrawcookie($this->_cookie["name"],
$this->_cookie["value"],
$this->_cookie["expire"],
$this->_cookie["path"],
$this->_cookie["domain"],
$this->_cookie["secure"],
$this->_cookie["httponly"]);
PD: Yep, lovely test password ;-)
The value I see on firebug for the cookie is:
oKWdbVLX9T+mbOut4swo/aXr0g5O/3ApqfWZ1GZlrwwMSTa+M4n8Uey0UQs827HB7tilc/OzUPWQxoNvnAIkP5CFGkvgn+j+I36qN6dB0HmOUPlkNXJlz8Tfqxrjf8Gx
My get cookie, where I've to decrypt the value is:
$this->_cookie["name"] = $cookie_name;
$this->_cookie["value"] = $_COOKIE[$cookie_name];
$cookie_value = base64_decode($this->_cookie["value"]);
$tv = mcrypt_module_open(MCRYPT_RIJNDAEL_256, null, "ctr", null);
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($tv), MCRYPT_RAND);
mcrypt_generic_init($tv, "t3stp4ssw0rd", $iv);
$this->_cookie["value"] = unserialize(mdecrypt_generic($tv, $cookie_value));
mcrypt_generic_deinit($tv);
mcrypt_module_close($tv);
return $_COOKIE[$cookie_name];
The problem is when I try to unserialize the value of the decrypted data. Anyone know where can be the problem?
Thank you in advance!
UPDATE:
$cookie_value = base64_decode($this->_cookie["value"]);
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_256, "", "cfb", "");
$ks = mcrypt_enc_get_key_size($td);
$key = substr(sha1("t3stp4ssw0rd"), 0, $ks);
$ivs = mcrypt_enc_get_iv_size($td);
$iv = substr($cookie_value, 0, $ivs);
$cookie_value = substr($cookie_value, $ivs);
mcrypt_generic_init($td, $key, $iv);
$cookie_value = mdecrypt_generic($td, $cookie_value);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
$this->_cookie["value"] = unserialize($cookie_value);
Returns me error Warning: mcrypt_generic_init(): Iv size incorrect; supplied length: 0, needed: 32
That offset error normally means that the length of one of the values doesn't correspond to the specified length denoted by the serialized data. In my experience, this normally comes down to:
as the previous poster said, backslashes being inserted to escape characters
Encoding issues. This normally arises where some characters are computed as having one byte when serialized, but when unserializing they suddenly have 2 bytes. This can happen when you have, say, an ISO-8859-1 character set, but then some operation changes it to UTF-8.
If I were to take a guess, I'd say that the second point is probably where your problem lies. Your procedure in the first instance is serialize->encrypt->base64_encode, then you reverse the sequence, but I suspect that, somewhere along the line, your character encoding is getting messed up.
Edited: Okay, I took a look at your code, and there's a problem with your encryption/decryption. Your decryption is not returning the decrypted value back. A while ago I came across this function (wish I could remember where so I can attribute it correctly) which is what I use for Mcrypt. It works for both encode and decode. Try it, and see if it sorts out your problem (the only thing it doesn't do is your base64_encode). I think your problem was that you were missing some required steps.
function encDec( $data, $key, $encrypt=true, $cypher='rijndael-128') {
if (function_exists('mcrypt_module_open')) {
# Serialize, if encrypting
if ( $encrypt ) { $data = serialize($data); }
# Open cipher module
if ( ! $td = mcrypt_module_open($cypher, '', 'cfb', '') )
return false;
$ks = mcrypt_enc_get_key_size($td); # Required key size
$key = substr(sha1($key), 0, $ks); # Harden / adjust length
$ivs = mcrypt_enc_get_iv_size($td); # IV size
$iv = $encrypt ?
mcrypt_create_iv($ivs, MCRYPT_RAND) : # Create IV, if encrypting
substr($data, 0, $ivs); # Extract IV, if decrypting
# Extract data, if decrypting
if ( ! $encrypt ) $data = substr($data, $ivs);
if ( mcrypt_generic_init($td, $key, $iv) !== 0 ) # Initialize buffers
return false;
$data = $encrypt ?
mcrypt_generic($td, $data) : # Perform encryption
mdecrypt_generic($td, $data); # Perform decryption
if ( $encrypt ) $data = $iv . $data; # Prepend IV, if encrypting
mcrypt_generic_deinit($td); # Clear buffers
mcrypt_module_close($td); # Close cipher module
# Unserialize, if decrypting
if ( ! $encrypt ) $data = unserialize($data);
}
return $data;
}
Make sure the quotes " in the cookie information are not escaped using back slashes. If they quotes are escaped, remove them before encrypting. See this thread -> PHP unserialize error at offset, works on some servers, not others

Categories