2013-11-22 52 views
1

我編寫的程序必須與基於PHP的Web服務交換加密數據。我使用C++和OpenSSL在CBC模式下使用AES-128加密數據。我將base64編碼的數據(IV和密文)發送到HTTP服務器,PHP必須使用Mcrypt解密數據。但是,只有第一個塊被成功解密,其他塊變成垃圾。 我完全不理解:我們如何才能在CBC模式下解密第一個塊?如果IV,密鑰或算法設置(如密鑰大小/塊大小/循環次數)錯誤,我們無法正確解密第一個塊。如果解密參數正常,那麼其他塊如何解密? 當我解密PHP無法用OpenSSL/C++解密的相同密文時,解密成功。 PHP也是如此:我可以在CBC模式下加密和解密數據。但由於任何原因,OpenSSL EVP_aes_128_cbc和mcrypt'rijndael-128'不兼容。 我的解密代碼如下:使用OpenSSL/C++和PHP/Mcrypt進行AES-128-CBC加密:僅對第一個塊進行解密

$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上添加受信任的根CA並使用Fiddler等工具攔截HTTPS流量通常是微不足道的;這就是爲什麼我決定使用自定義加密而不是SSL,所以atacker將不得不反彙編和修改我的代碼來破解系統,而不是像Fiddler這樣的標準工具用法。 – Vitaliy

+0

但是,一旦主密鑰「破解」,那麼整個系統的所有用戶都會受到威脅。你需要決定你是否在尋找安全或混淆。 – ntoskrnl

回答

0

那麼,錯誤是在C++端。我加密的數據部分來了,所以我不得不多次調用EVP_CipherUpdate;因爲在重複調用EVP_CipherUpdate拷貝到輸出緩衝區的數據太多而只有最後一個塊時,我不得不重複調用EVP_CipherInit_ex來清除OpenSSL上下文中的內部緩衝區。當我調用EVP_CipherInit_ex時,它重置IV,所以在某些點解密變得不可能之後。 解決的辦法是在每次EVP_CipherUpdate調用後將最後一個版本的IV(context.iv指向上一個IV,context.oiv指向原始指針)保存在緩衝區中,並將它傳遞給EVP_CipherInit_ex以允許OpenSSL按部分加密數據。當我這樣做時,mcrypt能夠解密整個數據,甚至刪除填充。 所以,mcrypt非常好,我看到的問題是我的程序錯誤,而不是mcrypt。

相關問題