mcrypt_encrypt fails to initialise - php

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

Related

PHP: How can I encrypt data in one file and then decrypt it in another file?

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

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.

Some Strings Won't Decrypt

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

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

mcrypt decoding errors

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.

Categories