Я пытаюсь зашифровать некоторые текстовые сообщения, используя mcrypt от php и шифрования Rijndael, но я не уверен в MCRYPT_MODE_modename (согласно руководству PHP они доступны «ecb», «cbc», «cfb», «ofb», nofb "или" stream ", но я читал, что на самом деле еще несколько). Я понятия не имею, что делают каждый или как их использовать.
Я читал две вещи, что режим ECB не должен использоваться, а MCRYPT_RAND – нет. Они не объяснили, почему. Для режима ECB я предполагаю, что это потому, что он всегда генерирует один и тот же зашифрованный вывод для одного и того же обычного текста (возможно, это может быть использовано для атаки), не знаю о MCRYPT_RAND (упоминается здесь @azz здесь ).
Мой вопрос в том, какой режим mcrypt я должен использовать, и было бы здорово увидеть пример использования PHP-кода, потому что все примеры, которые я нашел, используют ECB. Строки, которые я пытаюсь зашифровать, будут содержать только текст ascii и переменную длину, не более 500 символов.
ecb является самым простым и имеет недостатки, поэтому его не рекомендуется ( http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation ). cbc считается значительно более сильным, чем ecb. Некоторые из других могут быть даже сильнее, чем cbc, но все они связаны с потоком, поэтому cbc должен соответствовать вашим потребностям.
Из … http://us.php.net/manual/en/mcrypt.constants.php …
Я не уверен, почему рекомендуется MCRYPT_RAND, но может случиться так, что генератор случайных чисел системы на многих системах не считается действительно случайным. Есть только две альтернативы, и они могут быть недоступны в зависимости от вашей системы и версии PHP. Из … http://php.net/manual/en/function.mcrypt-create-iv.php …
Код ниже – это просто образец. Он работает, но я не могу подтвердить его силу.
<? PHP // Тестовый код $ objEncManager = новый DataEncryptor (); $ sensitiveData = "7890"; echo "Исходные данные: _". $ sensitiveData. "_ <br> <br>"; $ encryptedData = $ objEncManager-> mcryptEncryptString ($ sensitiveData); echo "Enc Data: _". $ encryptedData. "_ <br> <br>"; echo "Enc Data length:". strlen ($ encryptedData). "На <br>"; $ decryptedData = $ objEncManager-> mcryptDecryptString ($ encryptedData, $ objEncManager-> lastIv); echo "D-enc Data: _". $ decryptedData. "_ <br> <br>"; эхо "IV: _". $ objEncManager-> lastIv. "_ <br> <br>"; / * * Примечание. Эти функции не точно обрабатывают случаи, когда данные * зашифрованные имеют завершающие пробелы, поэтому данные * зашифрованные ими не должны быть. Ведущие пробелы - все в порядке. * * Примечание. Если ваши данные должны быть переданы через небезопасный безопасный носитель, вы должны * base64_encode, но это делает данные примерно на 33% больше. * * Примечание. Расшифровка IV должна быть такой же, как шифрование IV, поэтому шифрование * IV должен храниться или передаваться с зашифрованными данными. * От (http://php.net/manual/en/function.mcrypt-create-iv.php) ... * «IV предназначен только для предоставления альтернативного семени для процедур шифрования. * Этот IV не обязательно должен быть секретным, хотя это может быть желательно. * Вы даже можете отправить его вместе с вашим зашифрованным текстом без потери безопасности ». * * Примечание. Эти методы не делают никакой проверки ошибок на успех различных функций mcrypt * / класс DataEncryptor { const MY_MCRYPT_CIPHER = MCRYPT_RIJNDAEL_256; const MY_MCRYPT_MODE = MCRYPT_MODE_CBC; const MY_MCRYPT_KEY_STRING = "1234567890-abcDEFGHUzyxwvutsrqpo"; // Это должна быть случайная строка, рекомендуется 32 байта public $ lastIv = ''; публичная функция __construct () { // ничего не делать } / ** * Принимает строку открытого текста и возвращает зашифрованную версию * / public function mcryptEncryptString ($ stringToEncrypt, $ base64encoded = true) { // Установите вектор инициализации $ iv_size = mcrypt_get_iv_size (self :: MY_MCRYPT_CIPHER, self :: MY_MCRYPT_MODE); $ iv = mcrypt_create_iv ($ iv_size, MCRYPT_RAND); $ this-> lastIv = $ iv; // Шифрование данных $ encryptedData = mcrypt_encrypt (self :: MY_MCRYPT_CIPHER, self :: MY_MCRYPT_KEY_STRING, $ stringToEncrypt, self :: MY_MCRYPT_MODE, $ iv); // Данные могут нуждаться в передаче через недвоичный безопасный носитель, поэтому base64_encode при необходимости. (делает данные примерно на 33% больше) if ($ base64encoded) { $ encryptedData = base64_encode ($ encryptedData); $ this-> lastIv = base64_encode ($ iv); } else { $ this-> lastIv = $ iv; } // Возвращение зашифрованных данных return $ encryptedData; } / ** * Принимает строку открытого текста и возвращает зашифрованную версию * / public function mcryptDecryptString ($ stringToDecrypt, $ iv, $ base64encoded = true) { // Примечание: расшифровка IV должна быть такой же, как и шифрование IV, поэтому шифрование IV должно храниться во время шифрования // Возможно, данные были base64_encoded, поэтому при необходимости декодировать их (необходимо пройти перед расшифровкой) if ($ base64encoded) { $ stringToDecrypt = base64_decode ($ stringToDecrypt); $ iv = base64_decode ($ iv); } // Расшифровать данные $ decryptedData = mcrypt_decrypt (self :: MY_MCRYPT_CIPHER, self :: MY_MCRYPT_KEY_STRING, $ stringToDecrypt, self :: MY_MCRYPT_MODE, $ iv); // Возвращаем дешифрованные данные return rtrim ($ decryptedData); // rtrim необходимо для удаления дополнений, добавленных во время шифрования } } ?>
Режим ЕЦБ не является безопасным, поскольку он не вводит случайность в зашифрованные данные. Это в основном означает, что вы увидите те же шаблоны ввода на выходе (т. Е. См. Изображение, представленное здесь , это «зашифрованная» версия Tux, логотип Linux).
MT_RAND не считается защищенным, так как он использует генератор случайных чисел для операционной системы (функция rand()
PHP).
Для криптографических целей лучше использовать MCRYPT_DEV_RANDOM
(читать данные из / dev / random) или MCRYPT_DEV_URANDOM
(читать данные из / dev / urandom).
Наиболее часто используемые и безопасные режимы шифрования, доступные в Mcrypt, являются режимами CBC и CTR и подходят для общего использования. Всегда лучше использовать шифрование + аутентификацию (т.е. шифрование, а затем аутентификацию с использованием HMAC). Например, режим CBC без аутентификации зависит от атаки Padding Oracle .