1 回答

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