Каков параметр пароля для openssl_encrypt?

Документация PHP для функций openssl_encrypt

string openssl_encrypt (строка $ data, string $ method, string $ password [, int $ options = 0 [, string $ iv = ""]])

Может ли кто-нибудь помочь мне понять, что такое аргумент с именем $password ? Ответ может включать подтверждение или отказ от идеи, что помимо имени $password этот параметр действительно используется как ключ для шифрования.

Каков параметр пароля для openssl_encrypt ? Является ли это строкой пароля (только для печатаемых символов) или это ключ (с неприступными символами и терминаторами ASCII-Z)?


объяснение

Я застрял с документацией opensl_encrypt в PHP. Будучи хорошим парнем и пытаясь сделать «RTM», я не могу иметь большого смысла с неудовлетворительной документацией imho.

Проблема в том, что для меня существует разница между паролем и ключом, когда дело доходит до шифрования. Ключ – это непосредственно параметр, используемый для шифрования и, следовательно, обязательно определенного размера – «длина ключа» – то есть 128/256/512 бит в зависимости от требуемого шифрования и длины ключа. С другой стороны, пароль – это мое понимание читаемой пользователем строки, введенной через клавиатуру, которая может иметь разницу в любой длине и которая прежде используется для шифрования, сначала преобразованного в ключ .

следовательно, принципиальная разница:

  • пароль => ключ => шифрование
  • key => шифрование

К сожалению, в документации PHP openssl_encrypt я не могу найти никакой информации о том, как использовать ключ . Единственное, что предлагается, это параметр «пароль».

Может ли кто-нибудь дать мне клей, как можно использовать ключ? Конечно, я не хочу вводить ключ в качестве параметра пароля, так как я хочу, чтобы в шифровании использовался конкретный ключ . Я не хочу, чтобы этот ключ был просто пропущен в качестве параметра и служил для другого ключа, рассчитываемого из моего «ключа, ошибочного как пароль».

Кроме того, mistery продолжает смотреть на документацию относительно параметра вектора инициализации в той же функции openssl_encrypt . В нем просто говорится:

iv. Вектор инициализации, не содержащий NULL. и что iv должен быть строкой. Учитывая, что iv является нормальным, двоичные данные определенной длины и, например, строка, заканчивающаяся \ 0 (hex 0x00), может происходить внутри. Я озадачен желаемым форматом.

По сути, я очень сильно остался наедине с документацией PHP, в которой также говорится

ПРЕДУПРЕЖДЕНИЕ Эта функция в настоящее время не документирована; доступен только список его аргументов.

Обновить

Я провел некоторое тестирование и «попытался», чтобы помочь выяснить, что такое параметр пароля .

используя этот код:

 $pass="0123456789abcdefghijklmnob"; $iv="0123456789abcdef"; echo "using $pass results:\n"; echo openssl_encrypt("test secret string", 'aes-128-cbc', $pass,NULL,$iv); 

Я получаю этот результат:

 using 0123456789abcdefghijklmnob results: XjEeaLucY38Y6XEUceYMYKTebR4kOp3s727ipMl5KNc= 

Затем измените длину параметра « пароль »:

 $pass="0123456789abcdefg"; //hijklmnob"; $iv="0123456789abcdef"; echo "using $pass results:\n"; echo openssl_encrypt("test secret string", 'aes-128-cbc', $pass,NULL,$iv); 

Я получаю все тот же зашифрованный код:

 using 0123456789abcdefg results: XjEeaLucY38Y6XEUceYMYKTebR4kOp3s727ipMl5KNc 

Кажется, что в результате тестирования он не был проинформирован документацией о том, что пароль действительно рассматривается только до первых 16 байтов, которые, по-видимому, являются 128-битным ключом.

Меня пугает, что в такой чувствительной функции (используется для шифрования) документация плохая, и чрезмерный ввод одного плохо документированного параметра даже не предупреждается. Также я вполне уверен, что пароль должен быть назван ключевым, так как кажется, что эти 16 байт непосредственно представляют ключ.

Параметр $password действительно является ключом. Размер ключа зависит от режима AES, который вы используете (как вы знаете).

Как вы отметили в своем обновлении, для AES-128 для ключа используются только первые 16 символов / байтов. Для AES-256 это будут первые 32 символа.

Когда вы используете функции openssl_encrypt() и openssl_decrypt() , можно просто передать 32- openssl_decrypt() человеко-читаемый пароль для параметра $password / key.

Например, мой ввод для параметра пароля может быть $password = "This is 32 characters long......";

Большинство людей не любят писать пароль открытого текста, который является фиксированной длиной, поэтому они могут вычислять хэш и усекать его до нужной длины. Они будут использовать этот хеш в качестве ключа / пароля шифрования.

Например, я могу вычислить хеш MD5 пароля / фразы любой длины, которую я бы хотел, а затем использовать в качестве пароля / ключа AES:

 $plaintextPass = 'This is my password. This password is not exactly 32 bytes, but that is okay because I am hashing this.'; $password = hash('md5', $plaintextPass); /* the encryption key */ 

Имея это в наличии, независимо от того, какой пароль открытого текста я использую, у меня может быть строка с 32 символами / байтами в качестве ключа / пароля шифрования. Однако это уменьшает энтропию ключа / пароля шифрования, потому что нормальная 32-значная строка имеет большее пространство ключа, чем хэш-вывод MD5 (256 возможностей на каждый байт против 16 вариантов на каждый байт); однако 16 ^ 32 все же, безусловно, выходит за рамки грубой силы.

Off topic : В некоторых моих личных программах я работал над использованием 32 случайных сгенерированных байтов со значениями между 0-255. Это сделало бы энтропию ключа 256 ^ 32 шифрования, которая не поддается грубой силе. Это также будет устойчиво к атакам со словарем, поскольку 32 байта генерируются случайным образом с использованием криптографически защищенного генератора псевдослучайных чисел (CSPRNG) .

Итак, чтобы суммировать все это, да, параметр $password действительно является ключом, используемым для шифрования. Я согласен с вами, что в документации должно быть написано как $key , но хорошо. Пароль / ключ, который вы выбираете для шифрования, может быть общедоступным, если он удовлетворяет требованиям длины хэширующего ключа. Чтобы удовлетворить этим требованиям длины, можно хэшировать пароль для чтения / обычного текста и использовать хэш этого пароля в качестве ключа (параметр $password ), но пароль для чтения человеком должен быть длинным и уникальным.

Документация не очень ясна, однако этот комментарий к openssl_encrypt() PHP действительно помог мне, когда я пытался понять эту функцию. В комментарии приведен пример, а также полезная информация. Чтобы направить цитату автору комментария:

Поскольку параметр пароля, описанный здесь, не является паролем. … Это ключ! [Комментарий отредактированно мелким образом]