1 回答

TA貢獻1815條經驗 獲得超10個贊
PHP 代碼使用塊大小為 256 位的 Rijndael。SunJCE Provider 不支持此功能,僅支持 AES(它是 Rindael 的子集,塊大小為 128 位)。因此,第二個 Java 代碼片段也不起作用。因此必須使用像 BouncyCastle (BC) 這樣的第三方提供商。
Java/BC代碼中有兩個bug:
與 PHP 代碼相反,沒有應用 CBC。必須使用 來更改此設置
CBCBlockCipher
。BC 的零填充變體與 mcrypt 變體不同。BC 變體總是填充,即即使明文的長度已經對應于塊大小的整數倍(此處為 32 字節),mcrypt 變體也不會(即后者僅在明文長度不填充的情況下填充)對應于塊大小的整數倍)。
由于根據描述,明文已經對應于塊大小的整數倍,因此 mcrypt 變體不會填充。在 Java/BC 代碼中,如果根本不使用填充,就可以實現這一點。
但要小心:如果明文的長度不對應于塊大小的整數倍,那么當然必須使用填充(考慮到與 PHP 代碼中使用的零填充變體的兼容性)。
這兩個問題都可以通過更換線路來解決
ZeroBytePadding?c?=?new?ZeroBytePadding(); PaddedBufferedBlockCipher?pbbc?=?new?PaddedBufferedBlockCipher(rijndael,?c);
經過
BufferedBlockCipher?pbbc?=?new?BufferedBlockCipher(new?CBCBlockCipher(rijndael));
那么兩個代碼產生的密文是相同的。
一些附加說明:
使用密鑰作為 IV 通常沒有用。由于出于安全原因,IV 對于給定密鑰只能使用一次,因此每次加密都必須使用新密鑰。
通常在實踐中,每次加密都會生成一個新的、隨機的 IV。使用標準(即 AES)通常更安全,而不是使用塊大小為 256 位的 Rijndael,后者不是標準。
零填充并不可靠(此外,正如您所經歷的,有幾種變體可能會導致問題)。更可靠的是 PKCS7 填充。
- 1 回答
- 0 關注
- 179 瀏覽
添加回答
舉報