2013-11-22 2 views
1

Я пишу программу, которая должна обмениваться зашифрованными данными с веб-сервисом на основе PHP. Я использую C++ с OpenSSL для шифрования данных с AES-128 в режиме CBC. Я отправляю base64-кодированные данные (IV и шифротекст) на HTTP-сервер, а PHP должен расшифровать данные с помощью Mcrypt. Однако только 1-й блок дешифрован успешно, другие блоки становятся мусором. Я вообще не понимаю: как мы можем расшифровать 1-й блок только в режиме CBC? Если IV, ключевые или алгоритмические параметры, такие как размер ключа/размер блока/количество раундов, ошибочны, мы не можем получить 1-й блок, дешифрованный правильно; если параметры дешифрования в порядке, как возможно, что другие блоки не дешифрованы? Когда я дешифрую тот же зашифрованный текст, который PHP не может расшифровать с помощью OpenSSL/C++, дешифрование завершается успешно. То же самое верно для PHP: я могу шифровать и расшифровывать данные в режиме CBC. Но по какой-либо причине OpenSSL EVP_aes_128_cbc и mcrypt 'rijndael-128' несовместимы. Мой дешифрования код следующим образом:Шифрование AES-128-CBC с OpenSSL/C++ и PHP/Mcrypt: только 1-й блок дешифрован

$chipher = mcrypt_module_open('rijndael-128', '', 'cbc', ''); 
mcrypt_generic_init($chipher, $key, $iv); 
$decrypted_data = mdecrypt_generic($chipher, $encrypted_data); 

Является ли это ошибка в Mcrypt или есть ли способ для шифрования данных с помощью OpenSSL AES-128-CBC и расшифровать его с PHP Mcrypt?

+0

Есть ли причина, по которой вы не можете использовать стандартный протокол, например [TLS] (http://en.wikipedia.org/wiki/Transport_Layer_Security), который предназначен для использования в таком случае? – ntoskrnl

+0

Я думаю о защите от трещин; в Windows обычно тривиально добавлять доверенный корневой ЦС и перехватывать HTTPS-трафик с помощью инструмента, такого как Fiddler; поэтому я решил использовать собственное шифрование вместо SSL, поэтому атакующему придется разобрать и изменить мой код, чтобы взломать систему, а не просто использовать стандартные инструменты, такие как Fiddler. – Vitaliy

+0

Но как только главный секретный ключ «взломан», тогда все пользователи всей вашей системы скомпрометированы. Вам нужно решить, ищете ли вы безопасность или обфускацию. – ntoskrnl

ответ

0

Ну, ошибка была на стороне C++. Зашифрованные данные приходили по частям, поэтому мне приходилось многократно вызывать EVP_CipherUpdate; потому что при повторном вызове EVP_CipherUpdate копирует в выходной буфер слишком много данных и только последний блок, мне приходилось многократно вызывать EVP_CipherInit_ex для очистки внутренних буферов в контексте OpenSSL. И когда я вызвал EVP_CipherInit_ex, он сбросил IV, поэтому после некоторого дешифрования точки стало невозможно. Решение состоит в том, чтобы сохранить последнюю версию IV (context.iv указывает на последний IV, а context.oiv указывает на исходную) в буфере после каждого вызова EVP_CipherUpdate и передать его EVP_CipherInit_ex, чтобы позволить OpenSSL шифровать данные по частям. Когда я это сделал, mcrypt смог расшифровать целые данные и даже удалить дополнение. Итак, mcrypt отлично, и проблемы, которые я видел, это моя ошибка в программе, а не mcrypt.

Смежные вопросы