2013-10-15 5 views
3

У меня есть 2 encrypt & дешифровать функции, используя библиотеку PHP mcrypt.SHA1 Результат PHP mcrypt_decrypt

public function encrypt_string($input, $key) { 
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); 
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); 
    $cipher = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $input, MCRYPT_MODE_CBC, $iv); 
    return base64_encode($iv . $cipher); 
} 
public function decrypt_string($input, $key) { 
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); 
    $ciphertext = base64_decode($input); 
    $iv = substr($ciphertext, 0, $iv_size); 
    $cipher = substr($ciphertext, $iv_size); 
    return mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $cipher, MCRYPT_MODE_CBC, $iv); 
} 

Учитывая, что ключ генерируется:

$key = pack('H*', 'dfgsdighsdfksdhfosdfasdjldsfsdfgdfkgdl'); // a random key 

я могу успешно получить обратно ввода после шифрования & дешифрования.

Вот код:

$pass = '123456'; 
echo sha1($pass) . PHP_EOL; // prints 7c4a8d09ca3762af61e59520943dc26494f8941b 
$pass_cipher = encrypt_string($pass, $key); 
$pass_decrypt = decrypt_string($pass_cipher, $key); 
echo $pass_decrypt . PHP_EOL; // prints 123456 
echo sha1($pass_decrypt) . PHP_EOL; // prints f41b44dbecccaccfbb4ccf6a7fc4921c03878c6d 

Однако результат SHA1 отличается:

7c4a8d09ca3762af61e59520943dc26494f8941b // before encrypt & decrypt 
f41b44dbecccaccfbb4ccf6a7fc4921c03878c6d // after encrypt & decrypt 

Почему он отличается? Что я упустил ?

UPDATE:

Принятая ответ полезным. Для тех, кто хочет дополнительную информацию, здесь:

echo bin2hex($pass) . PHP_EOL; // prints 313233343536 
echo bin2hex($pass_decrypt) . PHP_EOL; // prints 31323334353600000000000000000000 

и после trim(), результат SHA1 работает, как и ожидалось, как пустые скрытые 0 удаляются.

+2

Сравните 'bin2hex ($ pass)' и 'bin2hex ($ pass_decrypt)'. – deceze

ответ

6

Проблема заключается в том, что ваш decrypt_string возвращает строку из 16 байтов, которая заполняется 0 байтами с правой стороны. Это проблема known for about 2 years.

Удали нулевые байты по правой линии, подобного этому:

return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $cipher, MCRYPT_MODE_CBC, $iv), "\0"); 

Будьте осторожны, чтобы не шифровать вещи с нулевым символом в конце, как и криптология функция в PHP работает, как если бы все строки были нуль- заканчиваются и не стесняются обрезать строку сначала \0 или возвращать бит \0 s, приклеенные к концу их вывода.

+0

Почему вы считаете, что ошибка? Проблема в том, что вы выбрали режим заполнения с потерей (нулевое заполнение), поэтому удаление невозможно надежно удалить. При шифровании следует использовать съемную прокладку. – CodesInChaos

+1

@CodesInChaos изменен на «проблема» - и это по крайней мере проблема, потому что это не очень хорошо документировано в dosc на PHP.net. Допустимые аргументы, возвращаемое значение заполнения не является. –

0

в зашифрованных данных + знак будет заменен пробелом. поэтому дешифрование не было выполнено.

Смежные вопросы