Я посмотрел на этот вопрос и хотел сделать это для себя. Когда я запустил этот код (взятый прямо из этого ответа ):
$textToEncrypt = "My super secret information."; $encryptionMethod = "AES-256-CBC"; // AES is used by the US gov't to encrypt top secret documents. $secretHash = "25c6c7ff35b9979b151f2136cd13b0ff"; //To encrypt $encryptedMessage = openssl_encrypt($textToEncrypt, $encryptionMethod, $secretHash, '1234567812345678'); //To Decrypt $decryptedMessage = openssl_decrypt($encryptedMessage, $encryptionMethod, $secretHash); //Result echo "Encrypted: $encryptedMessage <br>Decrypted: $decryptedMessage";
Однако я получаю предупреждение
openssl_encrypt(): Using an empty Initialization Vector (iv) is potentially insecure and not recommended
Поэтому я пошел и посмотрел документы , но документации нет ». Я нашел этот комментарий , но все равно не упоминал, что должен быть Инициализационный вектор, и как я должен его использовать. Может ли кто-нибудь просветить меня?
Я знаю, что мог бы сделать еще несколько Googleing, но Stackoverflow сначала появляется во многих результатах поиска. Я думал, что этот вопрос может быть полезен для всех, кто имел эту проблему.
IV – это, как правило, случайное число, гарантирующее, что зашифрованный текст уникален.
Чтобы объяснить, почему это необходимо, давайте притворимся, что у нас есть база данных имен людей, зашифрованных ключом «секрет» и нет IV.
1 John dsfa9p8y098hasdf 2 Paul po43pokdfgpo3k4y 3 John dsfa9p8y098hasdf
Если Джон 1 знает свой шифрованный текст (dsfa9p8y098hasdf) и имеет доступ к другим текстам шифрования, он может легко найти других людей по имени Джон.
Теперь на самом деле режим шифрования, который требует IV, всегда будет использовать его. Если вы не укажете IV, он автоматически настроится на пучок нулевых байтов. Представьте первый пример, но с константой IV (00000000).
1 John dsfa9p8y098hasdf 00000000 2 Paul po43pokdfgpo3k4y 00000000 3 John dsfa9p8y098hasdf 00000000
Чтобы предотвратить повторные шифрованные тексты, мы можем зашифровать имена, используя один и тот же «секретный» ключ и случайный IV:
1 John sdf875n90mh28458 45gh3546 2 Paul fg9087n5b60987nf 56897ngq 3 John gjhn0m89456vnler 8907345f
Как вы можете видеть, два текста шифрования «Джон» теперь различны. Каждый IV уникален и повлиял на процесс шифрования, что делает конечный результат уникальным. John 1 теперь не имеет понятия, какое имя пользователя 3.
Для дешифрования требуется использование того же самого кода, который был зашифрован, конечно, поэтому он должен храниться в базе данных. IV бесполезен без ключа, поэтому передача или хранение его с зашифрованным текстом не вызывает беспокойства.
Это слишком упрощенный пример, но правда в том, что использование IV не имеет серьезных последствий для безопасности.
Теперь ваш код, похоже, устанавливает IV (1234567812345678), но не использует его при расшифровке. Это наверняка потерпит неудачу.
Вы также можете использовать некоторые функции генерации IV в PHP. Я думаю, это должно сработать для вас:
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); $encryptedMessage = openssl_encrypt($textToEncrypt, $encryptionMethod, $secretHash, 0, $iv); $decryptedMessage = openssl_decrypt($encryptedMessage, $encryptionMethod, $secretHash, 0, $iv);
Для хранения / передачи вы можете просто объединить текст IV и шифрования так:
$data = $iv.$encryptedMessage;
Затем по извлечению вытащите IV для расшифровки:
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); $iv = substr($data, 0, $iv_size); $decryptedMessage = openssl_decrypt(substr($data, $iv_size), $encryptionMethod, $secretHash, 0, $iv);
Для получения дополнительной информации посетите библиотеку Mcrypt от PHP. Это довольно полнофункциональный и имеет множество примеров, многие из которых могут помочь вам с реализациями шифрования openssh. http://php.net/manual/en/function.mcrypt-encrypt.php