Я получаю эту ошибку:
Warning: mcrypt_decrypt(): The IV parameter must be as long as the blocksize
Это от шифрования переменной с кодом, который в основном совпадает с кодом на сайте руководства php ( http://php.net/manual/en/function.mcrypt-encrypt.php ). Он работал, когда все было вместе (я разделил его на две, чтобы использовать в качестве include()
файлы и добавил удобные входные и выходные переменные). Он шифрует значение, помещает его в переменную $ _GET, а затем на загрузку следующей страницы он расшифровывает его. Однако после дешифрования я получаю сообщение об ошибке. Я предполагаю, что это может иметь какое-то отношение к сохранению зашифрованной информации в переменной $ _GET, а затем ее чтению. Зашифрованный текст и идентификатор $ _GET в URL-адресе в одном экземпляре выглядит следующим образом: Last_Song_ID=mIyFkMdMgVgSZU18wD/vJ3bI8qf++ea1/NtGrsajKd4=
В этом файле (ошибка встречается в $ciphertext_dec, MCRYPT_MODE_CBC, $iv_dec);
у основания:
include('key.php'); $ciphertext_base64 = $de_in; $ciphertext_dec = base64_decode($ciphertext_base64); $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); echo $iv_size . "<br>"; # retrieves the IV, iv_size should be created using mcrypt_get_iv_size() $iv_dec = substr($ciphertext_dec, 0, $iv_size); # retrieves the cipher text (everything except the $iv_size in the front) $ciphertext_dec = substr($ciphertext_dec, $iv_size); # may remove 00h valued characters from end of plain text $plaintext_utf8_dec = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $ciphertext_dec, MCRYPT_MODE_CBC, $iv_dec); $de_out = $plaintext_utf8_dec;
вinclude('key.php'); $ciphertext_base64 = $de_in; $ciphertext_dec = base64_decode($ciphertext_base64); $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); echo $iv_size . "<br>"; # retrieves the IV, iv_size should be created using mcrypt_get_iv_size() $iv_dec = substr($ciphertext_dec, 0, $iv_size); # retrieves the cipher text (everything except the $iv_size in the front) $ciphertext_dec = substr($ciphertext_dec, $iv_size); # may remove 00h valued characters from end of plain text $plaintext_utf8_dec = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $ciphertext_dec, MCRYPT_MODE_CBC, $iv_dec); $de_out = $plaintext_utf8_dec;
Зашифрованный текст поступает из переменной $ _GET в основном файле, который исходит из следующего:
<?php # --- ENCRYPTION --- # the key should be random binary, use scrypt, bcrypt or PBKDF2 to # convert a string into a key # key is specified using hexadecimal include('key.php'); # show key size use either 16, 24 or 32 byte keys for AES-128, 192 # and 256 respectively $key_size = strlen($key); //echo "Key size: " . $key_size . "\n"; if(!isset($en_in)) $en_in = "No Input"; # create a random IV to use with CBC encoding $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); echo $iv_size . "<br>"; $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); # use an explicit encoding for the plain text $plaintext_utf8 = utf8_encode($en_in); # creates a cipher text compatible with AES (Rijndael block size = 128) # to keep the text confidential # only suitable for encoded input that never ends with value 00h # (because of default zero padding) $ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext_utf8, MCRYPT_MODE_CBC, $iv); # prepend the IV for it to be available for decryption $ciphertext = $iv . $ciphertext; # encode the resulting cipher text so it can be represented by a string $ciphertext_base64 = base64_encode($ciphertext); $en_out = $ciphertext_base64; ?>
в<?php # --- ENCRYPTION --- # the key should be random binary, use scrypt, bcrypt or PBKDF2 to # convert a string into a key # key is specified using hexadecimal include('key.php'); # show key size use either 16, 24 or 32 byte keys for AES-128, 192 # and 256 respectively $key_size = strlen($key); //echo "Key size: " . $key_size . "\n"; if(!isset($en_in)) $en_in = "No Input"; # create a random IV to use with CBC encoding $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); echo $iv_size . "<br>"; $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); # use an explicit encoding for the plain text $plaintext_utf8 = utf8_encode($en_in); # creates a cipher text compatible with AES (Rijndael block size = 128) # to keep the text confidential # only suitable for encoded input that never ends with value 00h # (because of default zero padding) $ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext_utf8, MCRYPT_MODE_CBC, $iv); # prepend the IV for it to be available for decryption $ciphertext = $iv . $ciphertext; # encode the resulting cipher text so it can be represented by a string $ciphertext_base64 = base64_encode($ciphertext); $en_out = $ciphertext_base64; ?>
Вы не можете передать базу 64 через параметр GET , так как это допустимые символы base64, которые могут столкнуться с параметрами GET:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 + / =
Таким образом, вы можете не получать весь GET, как ожидалось, а только часть. Вы можете сделать это, чтобы проверить, что:
Последняя строка кодирования:
echo strlen($en_out);
В начале кодирования:
echo strlen($de_in);
Если размеры не совпадают друг с другом, возникает ваша проблема, все это неправильно передается по причинам, упомянутым выше и связанным выше.
EDIT: о решении, как первый, так и второй ответ в связанном вопросе довольно хороши.