mcrypt encrypt добавляет s-связку '% 00' до конца строки

Работа с OAuth и шифрование ключей со следующей функцией со строкой, которую мы назовем «foo» (фактически токеном OAuth)

public function encrypt( $text ) { // add end of text delimiter $data = mcrypt_encrypt( MCRYPT_RIJNDAEL_128, $this->key, $text, MCRYPT_MODE_ECB, $this->iv ); return base64_encode( $data ); } 

Когда я дешифрую его с помощью обратной функции, я получаю:

Функция:

  public function decrypt( $text ) { $text = base64_decode( $text ); return mcrypt_decrypt( MCRYPT_RIJNDAEL_128, $this->key, $text, MCRYPT_MODE_ECB, $this->iv ); } 

Результат:

foo%00%00%00%00%00%00%00%00%00%00%00%00%00%00

Редактировать:

Посмотрев на него немного больше, я понял, что на самом деле это кодировка URL% 00, что означает, что мои строки каким-то образом дополняются нулевыми символами? Поэтому я использую trim (), чтобы избавиться от них, но я хотел бы понять, почему это происходит.

Rijndael – это блок-шифр , что означает, что он работает с кусками данных определенной длины (в этом случае 128 бит). Это означает, что если длина входного текста не кратная размеру блока, он должен быть дополнен, чтобы соответствовать. В этом случае отступы являются нулями; существует ряд других возможных схем заполнения, которые можно использовать, но если вы хотите, чтобы они с помощью mcrypt PHP, вам придется применять их вручную.

Вы можете исправить это с помощью этого метода, чтобы избавиться от отступов: в нашем случае мы используем Zend.

 $filter = new Zend_Filter_Decrypt(array('adapter' => 'mcrypt')); $filter->setVector($lpt->_seed); str_replace("\x0", '', trim($filter->filter(base64_decode($textToDecrypt)))); 

MCRYPT_MODE_ECB означает, что вы используете ECB, режим блочного шифрования. Блочные шифры могут обрабатываться либо для режима блочного шифрования, либо для режимов шифрования потока. Общими режимами блочного шифрования являются ECB и CBC, общий режим шифрования потока – CTR, более известный как режим работы счетчика.

MCRYPT_RIJNDAEL_128 – это реализация AES. AES – это шифр Rijndael с размером блока 128 бит и тремя возможными размерами клавиш, 128, 192 и 256 бит. Поэтому, если вы используете режим шифрования блочного шифрования, тогда вам нужно разделить простой текст размером 128 бит – 16 байт – каждый. Конечно, это оставляет вам вопрос, что делать, если последний блок не 16 байт.

PHP mcrypt_encrypt более или менее оставляет это для пользователя. Он заполняет 00 значными символами, если блок не заполнен до размера блока. Это нормально, если вход представляет собой строку; вы можете просто trim 00 символов из возвращаемой строки. Если входные данные, однако, двоичные данные, которые заканчиваются символом 00 чем этот символ, теряются (+ любой другой символ, который берется из начала и конца строки, конечно). Вы также можете отправить длину строки, зашифрованной вместе с открытым текстом, конечно.

Для лучшей схемы вам нужно только посмотреть на заполнение PKCS # 7. Несколько фрагментов кода для реализации дополнения можно найти в разделе комментариев mcrypt_encrypt .

mcrypt_encrypt настоящее время, похоже, не поддерживает режимы потоков для AES, поэтому опция не доступна, если вы хотите сохранить библиотеку PHP mcrypt.