我一直在研究 BouncyCastle 的加密 API 的 java 版本。我对PaddedBufferedBlockCipher类有点困惑。我理解(可能是错误的?)它的目的是用于增量处理加密,即从文件中读取数据。
当我调用一次 processBytes() 时,一次提供所有要加密的数据,然后 doFinal() 它按预期工作。但是,当我使用适当的偏移量/长度对 processBytes 进行多次调用,意图以较小的块进行处理,然后是 doFinal() 时,它失败了。谁能解释为什么以下代码失败?假设明文长度为 64 字节,并且以 4 x 16 字节块执行加密,则对值进行硬编码。
byte[] key= Hex.decode("a4ea1a7227e032c37f5635e70ba1bd38a4ea1a7227e032c37f5635e70ba1bd38");
byte[] iv= Hex.decode("a4ea1a7227e032c37f5635e70ba1bd38");
byte[] clearText= Hex.decode("28d3966905e33c063e7b74c7c7dcb2d688d48d53101d2a6901d365146faf0c9cde3da9ef37664a5e32e4e468f9b52f587d76b78caaf9d9823dd9eb2c1d700d7c");
BlockCipher bc = new AESFastEngine();
CBCBlockCipher cipher = new CBCBlockCipher(bc);
PaddedBufferedBlockCipher mode = new PaddedBufferedBlockCipher(cipher);
KeyParameter kp = new KeyParameter(key);
CipherParameters ivAndKey= new ParametersWithIV(kp, iv);
mode.init(true, ivAndKey);
byte[] outBuf = new byte[mode.getOutputSize(clearText.length)];
int blockSize = mode.getBlockSize();
// process the 64 bytes of clearText, in 4 x 16-byte chunks
for (int i = 0; i < 4; i++) {
mode.processBytes(clearText, i * blockSize, blockSize, outBuf, i * blockSize);
}
try {
// call doFinal on the last block (bytes 48->64)
mode.doFinal(outBuf, 48);
} catch (Exception e){}
System.out.println(new String(Hex.encode(outBuf)));
The expected output is: fe391ed41650f3b344ed3d200ffa3c55e71b1d97dbd91c0fbdd0989c3a48822e7e5230e9d6d073bc0752436d9bea9f26328a11586a290e712fbbf874ddfd4ba14e28600e55c7d6ac69467693320a82d3
But the result I'm getting is: 00000000000000000000000000000000fe391ed41650f3b344ed3d200ffa3c55e71b1d97dbd91c0fbdd0989c3a48822e328a11586a290e712fbbf874ddfd4ba14e28600e55c7d6ac69467693320a82d3
编辑
根据 PeterDettman 的建议修改代码:
int bytesProcessed = 0;
for (int i = 0; i < 4; i++) {
// Fixed to be '+='
bytesProcessed += mode.processBytes(clearText, i * blockSize, blockSize, outBuf, bytesProcessed);
}
mode.doFinal(outBuf, bytesProcessed);