mcrypt шифрует добавление связки «% 00» в конец строки - PullRequest
6 голосов
/ 15 апреля 2011

Работа с 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

Edit:

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

Ответы [ 3 ]

6 голосов
/ 15 апреля 2011

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

1 голос
/ 03 мая 2014

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.

1 голос
/ 18 мая 2011

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

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