Неверный размер ключа при портировании Crypto ++ AES шифрование на Mcrypt к Mcrypt PHP

StackOverflow https://stackoverflow.com/questions/4052594

Вопрос

Ранее мне удалось портировать некоторые C ++ Cryptopp Rijndael_128 CBC код CBC для Mcrypt PHP, но теперь у меня проблемы с режимом CFB. Результаты C ++ и PHP не совпадают (хорошо первые байтовые спички, но это может быть совпадение, все остальное не). С какой-то диагностикой он выглядит как Mcrypt PHP не устанавливает длину ключа?

Вот C ++ (диагностика и сопряжения удалены для простоты):

CFB_Mode<AES>::Encryption encryptor(g_encrypt_key, AES::DEFAULT_KEYLENGTH, g_encrypt_iv);

StringSource ss( sInput.c_str(), true, 
        new StreamTransformationFilter( encryptor, 
            new HexEncoder( new StringSink( sEncryptedOut ) )
        ));

И вот PHP:

$cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CFB, '')
mcrypt_generic_init($cipher, $g_encrypt_key, $g_encrypt_iv);

$sEncryptedOutput = mcrypt_generic( $cipher, $sInput);
mcrypt_generic_deinit($cipher);
mcrypt_module_close($cipher);

g_encrypt_key и g_encrypt_iv являются более 16 байтами длинными, а байты совпадают с версиями C ++ и PHP. Для версии PHP это двоичная строка, построенная из байтов (да, я проверил их идентичны).

Я добавил звонки в версию PHP, чтобы проверить $cipherРазмер блока, размер ключа и т. Д. Размер блока и IV размер IV являются 16; Поддерживаемые размеры ключей сообщаются как 16, 24 и 32 - все как ожидалось.

Там, где я думаю, что проблема в том, что ключей откладывается как 32 байта. Глядя на документы Mcrypt, единственным способом настройки ключей является поставка ключа требуемого размера. Но я передаю 16 байт-ключ! Так почему же это сообщает о наличии 32 байтового ключа? Если режим CFB должен использовать 32 байт-ключ, то почему Cryptopp принимает это как в порядке? Каково решение? Могу ли я заставить PHP использовать 16 байт-ключ, который был предоставлен? Или есть ли параметр, который мне не хватает, который по умолчанию для другой настройки в Cryptopp, чем в Mcrypt?

Я использую режим CFB, потому что хочу минимизировать длину результирующих зашифрованных данных. Несколько байтов, которые прокладывают бы, делают дело в этом приложении.

Мне нужно быть в состоянии зашифровать / дешифровать в C ++, но только шифрование в PHP. AES, возможно, чрезмерный накладки для моего приложения - минимум, который мне нужен, это «хорошая карабкаться байтами», так что функция отдельных байтов в данных не очевидна.

Это было полезно?

Решение

Это было некоторое время, но у меня были похожие проблемы с Mcrypt и OpenSSL, используя CFB пару лет назад. В конце концов, я обнаружил, что Mcrypt использовал другой размер цепи обратной связи по умолчанию, чем OpenSSL в режиме CFB. То есть я полагаю, что apenssl AES128 в CFB использовал размер блока и размер обратной связи 128 битов, а Mcrypt использовал размер блока 128бит и размер обратной связи с 8 битами. У меня нет способа подтвердить это, это было просто спекуляция в то время на основании чтения некоторых старого форума. Независимо от истинности этой теории, я был не единственным лицом или первым, чтобы иметь этот конкретный вопрос.

Решение для меня было использование Nofb как самостоятельно. Согласно Ссылка библиотеки PHP Mcrypt MCRYPT_MODE_NOFB заставляет цепочку обратной связи равную размер блока алгоритма, в этом случае 128-битный блок / обратная связь для AES128 (Rijndael), который соответствует тому, что мастерство Для модуля Mcrypt состояния о NOFB. Это хорошо, так как все, что я нашел, сказал, что обратная связь NOFB синхронно для размера блока. Таким образом, как MCRYPT, так и OpenSSL в NOFB, были теперь 128-битный ключ / IV / блок / обратная связь размером для AES128, и все работало нормально.

Что касается PHP отчетности 256bit ключевых ключей (32 байта), функция, которая возвращает текущий размер ключа шифров-алгоритма, фактически возвращает максимальный размер ключа, который нечетко не указан в документации. Я знаю это потому, что мой маленький класс, который я использую все время сейчас для различных проектов, отлично работает с OpenSSL и любыми другими библиотеками AES в CBC или Nofb. Это было бы не так, если Mcrypt прокладывался на мой 128бит (16 CHAR) ключ с дополнительными 128битами нулевой строки или что-то еще, и все равно не будет технически правильным.

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

Другие советы

Проверьте phpseclib:

http://phpseclib.sourceforge.net/

Вы можете установить размер ключа и размер блока на все, что вы хотите.

например. $ AES-> Speciledength (128) или $ AES-> Setkeillength (256);

У меня была эта проблема - пара очков. По умолчанию режим PHP Rijndael устанавливает цикл обратной связи до 8битов - быть AES - это должна быть одинаковая длина, что и IV / ключ.

Вы можете сделать это, используя режим «NCFB» вместо «CFB» или MCRYPT_MODE_CFB.

Полная информация о написании AES_CFB_128 Совместимый PHP находятся на этой безопасности stackexchange: AES CFB 128 Расшифровка / проблема шифрования между Erlang и PHP. Отказ Короче говоря (от Тома Порей):

... для CFB и OFB (которые отличаются друг от друга и не могут быть использованы взаимозаменяемо), вы должны беспокоиться о «длине обратной связи», которая не обязательно задокументирована с высокой ясностью в различных библиотеках Crypto. Как шифрование, так и дешифрование должно использовать одну и ту же длину обратной связи для взаимодействия.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top