Figure out mcrypt key when knowing hash and plain - php

i have 2 functions:
function Encrypt($sValue, $sSecretKey = "") {
if (!$sSecretKey) {
$sSecretKey = $GLOBALS['key'];
}
return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $sSecretKey, $sValue, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB),
MCRYPT_RAND))));
}
and
function Decrypt($sValue, $sSecretKey = "") {
if (!$sSecretKey) {
$sSecretKey = $GLOBALS['key'];
}
return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $sSecretKey, base64_decode($sValue), MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256,
MCRYPT_MODE_ECB), MCRYPT_RAND)));
}
is it possible to get the key which was used when i have a plain key and its hash?
PLAIN: checkingkeyisright
HASH: W0Kdv34iN5Gpkzc4DlisOw4Pynry/O9TLkUq6pwXxY8=

No, it is not. Recovering the key given the ciphertext and plaintext is something which cryptographic ciphers, such as Rijndael, are specifically designed to make infeasible.

Related

getting Scrambled text using mcrypt for securing url data in php

m using
public function encrypt($plain_str,$key)
{
$str= mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plain_str, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND));
$str = urlencode(base64_encode($str));
return $str ;
}
public function decrypt($cipher_str,$key)
{
$str = urldecode(base64_decode($cipher_str));
return mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $str, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND));
}
on crypting :201433~58~g#fds.com~20140820142427
i get : %2BAihYMLwpwrsmL4lSGGzwFTfonvdCyOb%2BCGEUJ%2F%2BE%2F7ZnvgwFRYFtlazQeSrVjUjyaaGZADK8%2BZyynIGxyt4VQ%3D%3D
on decrypting : %2BAihYMLwpwrsmL4lSGGzwFTfonvdCyOb%2BCGEUJ%2F%2BE%2F7ZnvgwFRYFtlazQeSrVjUjyaaGZADK8%2BZyynIGxyt4VQ%3D%3D
i get :201433~58~g#fds.com~20140820142427 back but
when string is malformed like some character removed
like this : %2BAihYMLwpwrsmL4lSGGzwFTfonvdCyOb%2BCGEUJ%2F%2BE%2F7Z
on decrypting i get : 201433~58~g#fds.com~201408201424O#¿W«Gݽˋ¯ È#'oP´ŸØw\Â⦑
How can i detect this anomoly ?
First of all, I'd like to list some flaws in your code:
Don't use ECB mode.
You are encrypting using MCRYPT_RIJNDAEL_128, but you're getting the IV size for MCRYPT_RIJNDAEL_256. (btw, IV is ignored in ECB mode, which is one of the reasons why not to use it)
You are also using MCRYPT_RAND as your randomness source, which is not secure. You should use MCRYPT_DEV_URANDOM (that is also the new default in PHP 5.6).
You don't have to urlencode() the resulting ciphertext, Base64 encoding is URL-safe.
Now, to answer your question ... this is done via a HMAC. The easiest way to use a HMAC is to prepend the cipher-text with it (which you should do with the IV as well; don't worry, it's not a secret):
public function encrypt($plainText, $encKey, $hmacKey)
{
$ivSize = mcrypt_get_iv_size('rijndael-128', 'ctr');
$iv = mcrypt_create_iv($ivSize, MCRYPT_DEV_URANDOM);
$cipherText = mcrypt_encrypt('rijndael-128', $encKey, $plainText, 'ctr', $iv);
$cipherText = $iv.$cipherText;
$hmac = hash_hmac('sha256', $cipherText, $hmacKey, true);
return base64_encode($hmac.$cipherText);
}
public function decrypt($cipherText, $encKey, $hmacKey)
{
$cipherText = base64_decode($cipherText);
if (strlen($cipherText) <= 32)
{
throw new Exception('Authentication failed!');
}
$recvHmac = substr($cipherText, 0, 32);
$cipherText = substr($cipherText, 32);
$calcHmac = hash_hmac('sha256', $cipherText, $hmacKey, true);
if ( ! hash_equals($recvHmac, $calcHmac))
{
throw new Exception('Authentication failed!');
}
$ivSize = mcrypt_get_iv_size('rijndael-128', 'ctr');
$iv = substr($cipherText, $ivSize);
$cipherText = substr($cipherText, $ivSize);
return mcrypt_decrypt('rijndael-128', $encKey, $cipherText, 'ctr', $iv);
}
Please note that the encryption key and HMAC key are different - they most NOT be the same key. Also, for Rijndael-128, you should create a 128-bit (or 16-byte) random key, it is not something that you can just type in with your keyboard. Here's how to generate one:
$encKey = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM);

Using mcrypt for password encryption in php

I want to know that can I use this encrypt-decrypt script for password encryption and put it into database?
And what will be the sql table password column structure(currently it is password varchar(32) NOT NULL).
Please note that this script is using a 32-byte hexadecimal key as encryption key.
<?php
define('ENCRYPTION_KEY', '32-byte hexadecimal encryption key');
function mc_encrypt($encrypt, $key)
{
$encrypt = serialize($encrypt);
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC), MCRYPT_DEV_URANDOM);
$key = pack('H*', $key);
$mac = hash_hmac('sha256', $encrypt, substr(bin2hex($key), -32));
$passcrypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $encrypt.$mac, MCRYPT_MODE_CBC, $iv);
$encoded = base64_encode($passcrypt).'|'.base64_encode($iv);
return $encoded;
}
function mc_decrypt($decrypt, $key)
{
$decrypt = explode('|', $decrypt);
$decoded = base64_decode($decrypt[0]);
$iv = base64_decode($decrypt[1]);
if(strlen($iv)!==mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC)){ return false; }
$key = pack('H*', $key);
$decrypted = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $decoded, MCRYPT_MODE_CBC, $iv));
$mac = substr($decrypted, -64);
$decrypted = substr($decrypted, 0, -64);
$calcmac = hash_hmac('sha256', $decrypted, substr(bin2hex($key), -32));
if($calcmac!==$mac){ return false; }
$decrypted = unserialize($decrypted);
return $decrypted;
}
?>
You should not store passwords - with or without encryption - unless strictly required (i.e. dealing with older protocols). Instead use a password hash function based on a PBKDF such as PBKDF2, bcrypt or scrypt.
Note that the encryption does not use AES but Rijndael with a block size of 256 bits. Also note that the key handling is suboptimal, it's easy to make mistakes with regards to the key parameter. Otherwise the code looks OK at first glance.

error in php crypt

i use such f-n to encrypt\decrypt
<?
//Encrypt Function
function mc_encrypt($encrypt, $mc_key) {
 $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND);
$passcrypt = trim(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $mc_key, trim($encrypt), MCRYPT_MODE_ECB, $iv));
$encode = base64_encode($passcrypt);
return $encode;
}
// Decrypt Function
function mc_decrypt($decrypt, $mc_key) {
$decoded = base64_decode($decrypt);
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND);
$decrypted = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $mc_key, trim($decoded), MCRYPT_MODE_ECB, $iv));
return $decrypted;
}
?>
if i call mc_encrypt('test', 'pass') all decrypts ok, but if i call mc_encrypt('test=value', 'pass') i can't decrypt. why? and what must i do?
You should tell us what happens, i.e. what code you call, what you expect, and what comes out. We cannot guess what "I can't decrypt" means.
I can give you one suggestion already though:
$passcrypt = trim(mcrypt_encrypt(
MCRYPT_RIJNDAEL_256, $mc_key, trim($encrypt), MCRYPT_MODE_ECB, $iv));
Don't mess with the input data [trim($encrypt)]. If the caller wants to trim the string, leave it to them to do it. Otherwise, if your input string has whitespace to trim, you will end up encrypting a different string than was passed in. That can only end in tears.

How to encrypt data at rest?

HOw do i encrypt data at rest? I know SSL encrypts in transit.
How do i integrate AES 256 bit encryption in phpmyadmin?
Here's an example using mcrypt:
<?
// Encrypt Function
function mc_encrypt($encrypt, $mc_key) {
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND);
$passcrypt = trim(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $mc_key, trim($encrypt), MCRYPT_MODE_ECB, $iv));
$encode = base64_encode($passcrypt);
return $encode;
}
// Decrypt Function
function mc_decrypt($decrypt, $mc_key) {
$decoded = base64_decode($decrypt);
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND);
$decrypted = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $mc_key, trim($decoded), MCRYPT_MODE_ECB, $iv));
return $decrypted;
}
?>
Read more about the library here: http://php.net/manual/en/ref.mcrypt.php
EDIT:
If i misunderstood the question and you wanted to do this in mysql you can use the mysql built in aes encryption functions:
INSERT INTO users SET name = "User1", password = AES_ENCRYPT("password", "encryption key");
and:
SELECT AES_DECRYPT(password, "encryption key") FROM users WHERE id = 1;
However this is just aes128, if you want to use aes256 directly in mysql you would have to modify the source and recompile.
Read more about it here:
http://dev.mysql.com/doc/refman/5.5/en/encryption-functions.html#function_aes-encrypt
If you're talking about straight encrypt/decrypt of data then there are some good examples in the php.net manuals.
You would then encrypt your data before inserting it into your database, you wouldn't encrypt anything through phpMyAdmin.

mcrypt_decrypt return strange code

I tried to encrypt an array then decrypt it back to string by calling a function, it's seem return the correct value if I does all encrypt and decrypt at once time in the function, however, if I return the encrypt value, then call the function again to decrypt it will return me some strange code.
Example 1:
public main()
{
$dataArray = array("one"=>1, "two"=>2, "three"=>3);
$a = $this->encryptDecryptInfo(json_encode($dataArray),$this->key);
var_dump($a);
}
public function encryptDecryptInfo($text,$key)
{
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256,
$text= base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_CFB, $iv));
return mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, base64_decode($text), MCRYPT_MODE_CFB, $iv);
}
This will return me the correct value which is string(27) "{"one":1,"two":2,"three":3}"
Example 2:
public main()
{
$dataArray = array("one"=>1, "two"=>2, "three"=>3);
$a = $this->encryptDecryptInfo(json_encode($dataArray),$this->key,"encrypt");
$b = $this->encryptDecryptInfo($a,$this->key,"decrypt");
var_dump($b);
}
public function encryptDecryptInfo($text,$key,$type)
{
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CFB), MCRYPT_RAND);
if($type == "encrypt")
return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_CFB, $iv));
else return mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, base64_decode($text), MCRYPT_MODE_CFB, $iv);
}
However if I do my code in this way, it will return me strange value which is like this string(27) "�ÔérôŸY éXgíœÈÐN*é౜CµÖ" .
Deos anyone know why this is happen? Both encrypt and decrypt coding are the same for example 1 and example 2, but why it will return strange code in example instead? Any way to fix this issue?
I think this is encoding issue look for UTF here - http://php.net/manual/en/function.base64-encode.php in the comments there is a UTF8 safe encoding function.
By passing the parameters left and right you are changing the encoding and you loose it in the translation. Welcome to PHP :)
You must use the same IV for decryption. Just save it along with encrypted data, for example:
if($type == "encrypt") {
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CFB), MCRYPT_RAND);
return base64_encode($iv . '##' .
mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_CFB, $iv));
} else {
list($iv, $data) = explode('##', base64_decode($text));
return mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $data, MCRYPT_MODE_CFB, $iv);
}
I had a similar issue. In the database I originally set it up for 16 characters. When I changed to encrypting, I forgot to change that number so the entire encrypted value was not stored. Once I corrected this it returned normal characters :)

Categories