Как правильно работать с php-функцией Mcrypt? Не хочет восстанавливать зашифрованные данные

Может быть кто-нибудь подскажет где тут ошибка?

	// взято на http://stackoverflow.com/questions/5465148

	define('SECRET',md5('blabla'));

	function encrypt($value){
		$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
		$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
		return mcrypt_encrypt(MCRYPT_RIJNDAEL_256, SECRET, $value, MCRYPT_MODE_ECB, $iv);
	}

	function decrypt($value){
		$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
		$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
		return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, SECRET, $value, MCRYPT_MODE_ECB, $iv));
	}
	
	if ( $hash== '' ) // $hash это сам хеш передаваемый в урле
		print base64_encode(encrypt($pass)); // шифрование
	else 
		print decrypt(base64_decode($hash));

Почему-то функция decrypt не верно восстанавливает данные пришедшие в урле, хотя если сразу после шифрования вывести

print decrypt(base64_decode(base64_encode(encrypt($pass))));

то все дешифруется правильно.

В чем может быть дело?
  • Вопрос задан
  • 12227 просмотров
Решения вопроса 1
AGvin
@AGvin
Вот юолее простой пример использования mcrypt_encrypt / mcrypt_decrypt:
<?php
function encrypt_data($key, $text){
  $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
  $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
  $encrypted_text = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv);
  return $encrypted_text;
}

function decrypt_data($key, $text){
  global $encryptionkey;
  $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
  $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
  $decrypted_text = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv);
  return $decrypted_text;
}

$key = 'This is a very secret key';
$text = "Meet me at 11 o'clock behind the monument.";
echo $text .':'. mb_strlen ($text)."\n";

$crypttext = encrypt_data ($key,$text);

$decrypttext = decrypt_data ($key, $crypttext) ;
echo  $decrypttext.':'. mb_strlen ($decrypttext)."\n";
var_dump($decrypttext);


В результате выполнения:
[AGvin@localhost public]$ php test.php 
Meet me at 11 o'clock behind the monument.:42
Meet me at 11 o'clock behind the monument.:64
string(64) "Meet me at 11 o'clock behind the monument.\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"


В качестве лечения, можно использовать $decrypttext= rtrim($decrypttext, '\0');

или поправить функцию decrypt_data:

<?php
function decrypt_data($key, $text){
  global $encryptionkey;
  $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
  $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
  $decrypted_text = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv);
  return rtrim($decrypted_text, '\0');;
}
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
truekenny
@truekenny
Результат base64_encode в конце может иметь символы равно, которые надо экранировать в запросе GET.
Ответ написан
Комментировать
unglued
@unglued
Если нужна простота и скорость:

<?php
/* key and string */
$key = md5("key", true);
$input = "input";

/* encode */
$encrypted_data = urlencode(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $input, MCRYPT_MODE_ECB)));

/* decode */
$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256,$key, base64_decode(urldecode($encrypted_data)),MCRYPT_MODE_ECB);
Ответ написан
Комментировать
DjPhoeniX
@DjPhoeniX
Hardcore iOS & ESP developer & DJ
Насколько я знаю про AES, вектор инициализации при шифровании и расшифровке должен быть одинаковым. А у вас при каждом encrypt/decrypt
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);

То, что при выполнении функций «подряд» результат верный — списываю на особенности random.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы