mcrypt decoding errors - php

I have a few issues with the following php functions (part of a bigger class).
//encode
public function acc_pw_enc($text, $key) {
$text_num = str_split($text, 8);
$text_num = 8 - strlen($text_num[count($text_num)-1]);
for ($i=0; $i < $text_num; $i++) {
$text = $text . chr($text_num);
}
$cipher = mcrypt_module_open(MCRYPT_TRIPLEDES, '', 'cbc', '');
mcrypt_generic_init($cipher, $key, 'fYfhHeDm');
$decrypted = mcrypt_generic($cipher, $text);
mcrypt_generic_deinit($cipher);
return base64_encode($decrypted);
}
//decode
public function acc_pw_dec($encrypted_text, $key) {
$cipher = mcrypt_module_open(MCRYPT_TRIPLEDES, '', 'cbc', '');
mcrypt_generic_init($cipher, $key, 'fYfhHeDm');
$decrypted = mdecrypt_generic($cipher, base64_decode($encrypted_text));
mcrypt_generic_deinit($cipher);
$last_char = substr($decrypted, -1);
for($i=0; $i < 8-1; $i++) {
if(chr($i) == $last_char) {
$decrypted = substr($decrypted, 0, strlen($decrypted)-$i);
break;
}
}
return rtrim($decrypted); //str_replace("?", "", $decrypted);
}
So for exampe if i encrypt the string 'liloMIA01' with the salt/key 'yBevuZoMy' i will get '7A30ZkEjYbDcAXLgGE/6nQ=='.
I get liloMIA01 as the decrypted value, i tried using rtrim but it didn't work.

A big problem with mcrypt is it doesn't support any padding algorithm when used with block ciphers like 3DES. So you will get garbage at the end if the data is not multiple of block size (8 bytes in this case).
You need to pad the data properly using pkcs#5 or add a length field.

Related

Why AES Decrypt code doesn't work in php 7.2

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.

PHP 3DES decrypt showed weird(bad) characters

I have a PHP form for which I have implemented 3des encryption/decryption. After submitting and inserting information into database from the front-end, I want to read out the information in the back-end.
After decryption my form's information instead of correct characters it just return some bad charater for me such as : �СU�k�8��t�ó�2(�f�B. How can I solve this issue?
Here is my source code:
<?php
function encrypt($clear, $key , $base64 = true)
{
if (!$clear)
return '';
$clear = pack("a*H2", $clear, "80");
if (function_exists('mcrypt_module_open') &&
($td = mcrypt_module_open(MCRYPT_TripleDES, "", MCRYPT_MODE_CBC, "")))
{
$iv = create_iv(mcrypt_enc_get_iv_size($td));
mcrypt_generic_init($td, $key, $iv);
$cipher = $iv . mcrypt_generic($td, $clear);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
}
else {
#include_once('des.inc');
if (function_exists('des')) {
$des_iv_size = 8;
$iv = create_iv($des_iv_size);
$cipher = $iv . des($key, $clear, 1, 1, $iv);
}
else {
raise_error(array(
'code' => 500, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
'message' => "Could not perform encryption; make sure Mcrypt is installed or lib/des.inc is available"
), true, true);
}
}
return $base64 ? base64_encode($cipher) : $cipher;
}
function decrypt($cipher, $key , $base64 = true)
{
if (!$cipher)
return '';
$cipher = $base64 ? base64_decode($cipher) : $cipher;
if (function_exists('mcrypt_module_open') &&
($td = mcrypt_module_open(MCRYPT_TripleDES, "", MCRYPT_MODE_CBC, "")))
{
$iv_size = mcrypt_enc_get_iv_size($td);
$iv = substr($cipher, 0, $iv_size);
// session corruption? (#1485970)
if (strlen($iv) < $iv_size)
return '';
$cipher = substr($cipher, $iv_size);
mcrypt_generic_init($td, $key, $iv);
$clear = mdecrypt_generic($td, $cipher);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
}
else {
#include_once('lib/des.inc');
if (function_exists('des')) {
$des_iv_size = 8;
$iv = substr($cipher, 0, $des_iv_size);
$cipher = substr($cipher, $des_iv_size);
$clear = des($this->config->get_crypto_key($key), $cipher, 0, 1, $iv);
}
else {
raise_error(array(
'code' => 500, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
'message' => "Could not perform decryption; make sure Mcrypt is installed or lib/des.inc is available"
), true, true);
}
}
/*-
* Trim PHP's padding and the canary byte; see note in
* rcmail::encrypt() and http://php.net/mcrypt_generic#68082
*/
$clear = substr(rtrim($clear, "\0"), 0, -1);
return $clear;
}
function create_iv($size)
{
$iv = '';
for ($i = 0; $i < $size; $i++)
$iv .= chr(mt_rand(0, 255));
return $iv;
}
**echo decrypt('ijvdfvf1==+Ac44tgLHdAL+w7O2MiiIZplC','s&gs1?m5l8PQIOGckvxDT4kR',true);**
?>
I want to encrypt and decrypt UTF-8 characters in my form.
I think you have forgotten one $cipher = substr($cipher, $des_iv_size); in the mcrypt part of your decrypt function.
Furthermore you should explicitly convert strings to (and from) UTF-8 encoding if you want to support UTF-8.
Finally it seems you are using single DES if 3DES is not available. Is that on purpose?

3DES PHP Encryption Not Decrypting Properly

I'm using the following code to encrypt information that will be passed to an external site on the end of the link URL. Right now it's able to do the encrypting and decrypting itself, but when I go to online Decryptors (online-domain-tools.com, tools4noobs.com) I'm seeing extra symbols added or it's not showing the right content whatsoever. Of course I'm new to this. What I have, I have pieced together from other questions (php-equivalent-for-java-triple-des-encryption-decryption, php-equivalent-encryption-decryption-tripledes, php-encrypt-decrypt-with-tripledes-pkcs7-and-ecb). Thanks for any help or direction!
I can only use 3DES with CBC.
PHP Code:
$key = "12AB12AB12AB12AB12AB12AB";
$iv = "12AB12AB";
$cipher = mcrypt_module_open(MCRYPT_3DES, '', 'cbc', '');
// MESSAGE
$message = "email=billysmith#afakeemail.com&account=987654321&role=2";
echo 'Message::: ' .$message .'<br />';
// ENCRYPTED
$encrypted = Encryptor($message);
echo 'Encrypted::: ' .$encrypted .'<br />';
// DECRYPTED
$decrypted = Decryptor($encrypted);
echo 'Decrypted::: ' .$decrypted .'<br />';
function Encryptor($buffer) {
global $key, $iv, $cipher;
// get the amount of bytes to pad
$extra = 8 - (strlen($buffer) % 8);
// add the zero padding
if($extra > 0) {
for($i = 0; $i < $extra; $i++) {
$buffer .= "\0";
}
}
mcrypt_generic_init($cipher, $key, $iv);
$result = bin2hex(mcrypt_generic($cipher, $buffer));
mcrypt_generic_deinit($cipher);
return $result;
}
function Decryptor($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);
}
To be short: Your code is correct. You can't test your encryption with provided tools.
Both tools do not allow to enter your IV.
The IV should be unique and can be transferred publicly.
Using wrong IV by decoding gives you wrong part at the beginning of decrypted data.
Here is OO version. It uses zero padding (built in PHP), like your code. It also makes no padding **, if the original message is already aligned.
<?php
$key = "12AB12AB12AB12AB12AB12AB";
$iv = "12AB12AB";
// MESSAGE
$message = "email=billysmith#afakeemail.com&account=987654321&role=22";
echo 'Message::: ' . $message . PHP_EOL;
$cryptor = new Crypt3Des();
$encryptedMessage = $cryptor->encrypt($message, $key, $iv);
echo 'Encrypted::: ' . bin2hex($encryptedMessage) . PHP_EOL;
$decryptedMessage = $cryptor->decrypt($encryptedMessage, $key, $iv);
echo 'Decrypted::: ' . $decryptedMessage . PHP_EOL;
class Crypt3Des
{
private $cipher;
public function __construct()
{
$this->cipher = mcrypt_module_open(MCRYPT_3DES, '', 'cbc', '');
}
public function encrypt($data, $key, $iv)
{
mcrypt_generic_init($this->cipher, $key, $iv);
$result = mcrypt_generic($this->cipher, $data);
mcrypt_generic_deinit($this->cipher);
return $result;
}
public function decrypt($encryptedData, $key, $iv)
{
mcrypt_generic_init($this->cipher, $key, $iv);
$result = mdecrypt_generic($this->cipher, $encryptedData);
mcrypt_generic_deinit($this->cipher);
$result = rtrim($result, "\0");
return $result;
}
}
// Before 5.4.0
if (!function_exists('hex2bin')) {
function hex2bin($data)
{
$len = strlen($data);
return pack("H" . $len, $data);
}
}

Looking to convert this JAVA/PHP Encryption code to C#

I work in PHP and looking to convert a piece of code from JAVA/PHP to C# related to encryption , I am novice in C# can anyone help me?
Code is picked from http://www.androidsnippets.com/encrypt-decrypt-between-android-and-php
Also given below - Please help me :
====================================================
/****/
/PHP/
<?php
class MCrypt
{
private $iv = 'fedcba9876543210'; #Same as in JAVA
private $key = '0123456789abcdef'; #Same as in JAVA
function __construct()
{
}
function encrypt($str) {
//$key = $this->hex2bin($key);
$iv = $this->iv;
$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 bin2hex($encrypted);
}
function decrypt($code) {
//$key = $this->hex2bin($key);
$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 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;
}
}
Look at MSDN (MicroSoft Developer Network),
at the end of the page there are some examples called RijndaelManaged_Example that show how to encrypt and decypt
http://msdn.microsoft.com/en-us/library/f9df14hc(v=vs.110).aspx

Class not found?

I am using MCrypt.php
index.php
include("MCrypt.php");
$crypter = new MCrypt();
MCrypt.php exists in same directory.
when I run index.php I get
Fatal error: Class 'MCrypt' not found in
/home/username/project/index.php on line 5
UPDATE: I have tried including just MCrypt.php but got the same error. I tried renaming to .class.php and got the same error.
class MCrypt {
private $iv = 'fedcba9876543210'; #Same as in JAVA
private $key = '0123456789abcdef'; #Same as in JAVA
function __construct() {
}
function encrypt($str) {
$iv = $this->iv;
$td = mcrypt_module_open('rijndael-128', '', 'cbc', $iv);
mcrypt_generic_init($td, $this->key, $iv);
$str = $this->padString($str);
$encrypted = mcrypt_generic($td, $str);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return base64_encode($encrypted);
}
function decrypt($code) {
$code = base64_decode($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 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;
}
private function padString($source) {
$paddingChar = ' ';
$size = 16;
$x = strlen($source) % $size;
$padLength = $size - $x;
for ($i = 0; $i < $padLength; $i++) {
$source .= $paddingChar;
}
return $source;
}
}
your php file has to start with the php opening tag. the first line, before the class, has to be <?php
like this:
<?php
class MCrypt {
...
Including instead of MCrypt.class.php, the file is MCrypt.php if the file is called MCrypt.php.

Categories