Дешифрование данных с помощью инструмента командной строки openssl

Я должен следовать коду, и насколько я знаю, он правильный, но он не работает. Я пытаюсь кодировать данные с помощью PHP Mcrpyt, а затем декодировать его с помощью инструмента командной строки openssl.

Это мой PHP-код:

/* * Convert a normal ascii string to a hexadecimal string. * Complement of hexToString(). */ function stringToHex($str) { $hex_str = ""; for ($i = 0; $i < strlen($str); ++$i) { $hex_str .= sprintf("%02X", ord($str[$i])); } return $hex_str; } $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_DEV_RANDOM); $block_size = mcrypt_get_block_size("rijndael-128", "cbc"); $pad = $block_size - (strlen($data) % $block_size); $data .= str_repeat(chr($pad), $pad); $encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, "1234567812345678", $data, MCRYPT_MODE_CBC, $iv); $message = stringToHex($iv) . base64_encode($encrypted); 

Я добавляю IV в закодированное сообщение. Например, IV составляет 00000000000000000000000000000000 (размер 32), затем я использую следующую команду для дешифрования:

 openssl enc -d -aes-128-cbc -A -nosalt -K 31323334353637383132333435363738 -iv 00000000000000000000000000000000 -in file_in > file_out 

Также обратите внимание, что 1234567812345678 – это hex 31323334353637383132333435363738. Но я все равно получаю то же сообщение об ошибке:

bad decrypt 1340: error: 0606506D: подпрограммы с цифровым конвертом: EVP_DecryptFinal_ex: неправильная длина конечного блока: ./ crypto / evp / evp_enc.c: 454:

Кто угодно?

Спасибо заранее, вся любовь, Джори.

Ну, я проверил ваш код, и он сработал с несколькими изменениями.

1) Вход для openssl должен включать только зашифрованный текст, а не предварительный IV (поскольку ваш код был неполным, я не был уверен, действительно ли вы лишили IV из зашифрованного текста перед его обработкой с помощью openssl).

2) В команде openssl отсутствовал параметр (-a), необходимый для фактического декодирования Base64 (просто использование -A не включит это). Опять же, поскольку ваше описание было неполным, я не был уверен, действительно ли вы Base64-декодировали сообщение, прежде чем хранить его в файле file_in.

Чтобы быть полным, это код, который я использовал для проверки вашего кода (я запускаю его из командной строки, не используя веб-сервер).

 <?php $data = " This is a test. This is only a test. Stack Overflow is collaboratively built and maintained by your fellow programmers. "; $keybin = "1234567812345678"; //$iv = mcrypt_create_iv (mcrypt_get_iv_size (MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_DEV_RANDOM); $iv = mcrypt_create_iv (mcrypt_get_iv_size (MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_RAND); $block_size = mcrypt_get_block_size ("rijndael-128", "cbc"); $pad = $block_size - (strlen ($data) % $block_size); $data .= str_repeat (chr ($pad), $pad); $encrypted = mcrypt_encrypt (MCRYPT_RIJNDAEL_128, $keybin, $data, MCRYPT_MODE_CBC, $iv); $message = base64_encode ($encrypted); echo "CIPHERTEXT= " . $message . "\n"; echo "IV= " . bin2hex ($iv) . "\n"; echo "KEY= " . bin2hex ($keybin) . "\n"; echo "\nTest with:\n\necho $message | openssl enc -d -aes-128-cbc -nosalt -a -A -K " . bin2hex ($keybin) . " -iv " . bin2hex ($iv) . "\n\n"; ?> 

Другие незначительные отличия заключались в том, что я использовал bin2hex для PHP.

Он будет выдавать такой результат, как:

 CIPHERTEXT= /e81Ua/0jxgff3j5GjKXaNilv5WqPYV7yRYy4AzsTUmGQeK0hcMjuUYp1Yrfthaox9zTI0DeDQT4fba+y/qTQahZpYRAKcZa209RVg4W1HrySfZPMRCxE+y8r8scL3Xmj+oMGFpS+cDo111OPqwHhNwWSHbMlsoJLvMr70ZiQmE= IV= 56c7c7248c68127cee8f0e54d89b4fc1 KEY= 31323334353637383132333435363738 Test with: echo /e81Ua/0jxgff3j5GjKXaNilv5WqPYV7yRYy4AzsTUmGQeK0hcMjuUYp1Yrfthaox9zTI0DeDQT4fba+y/qTQahZpYRAKcZa209RVg4W1HrySfZPMRCxE+y8r8scL3Xmj+oMGFpS+cDo111OPqwHhNwWSHbMlsoJLvMr70ZiQmE= | openssl enc -d -aes-128-cbc -nosalt -a -A -K 31323334353637383132333435363738 -iv 56c7c7248c68127cee8f0e54d89b4fc1 

Ошибка, которую вы имели (плохая расшифровка, подпрограммы с цифровым конвертом EVP_DecryptFinal_ex), обычно означает неправильный ключ или поврежденный зашифрованный текст. Я думаю, что в вашем примере проблема была поврежденным зашифрованным текстом, вызванным предварительным IV и / или отсутствием декодирования Base64.

openssl enc использует дополнение PKCS # 5, которое вы реализуете, за исключением обязательного блока заполнения, если данные кратно размеру блока. Поскольку вы тестируете 16 байтов (это размер блока), вам нужно добавить еще 16 байт, содержащих chr(16) .