Java 为什么cipher.getOutputSize()返回的值高于所需值?
我正在尝试解密一个用AES256 CBC加密的文件,下面是我的代码:Java 为什么cipher.getOutputSize()返回的值高于所需值?,java,encryption,bouncycastle,Java,Encryption,Bouncycastle,我正在尝试解密一个用AES256 CBC加密的文件,下面是我的代码: PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESFastEngine())); cipher.init(false, new ParametersWithIV(new KeyParameter(key), iv)); byte[] outBuf = new byte[cipher.getOutp
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESFastEngine()));
cipher.init(false, new ParametersWithIV(new KeyParameter(key), iv));
byte[] outBuf = new byte[cipher.getOutputSize(data.length)];
int processed = cipher.processBytes(data, 0, data.length, outBuf, 0);
processed += cipher.doFinal(outBuf, processed);
这很简单,但是cipher.getOutputSize(data.length)
总是返回一个大于所需的值。我总是在缓冲区的末尾出现一些奇怪的字符
我已尝试解密两个html文件,以下是它们的结尾:
</HTML>����������������
// Processed: 9304 Size: 9312
����������������
//加工:9304尺寸:9312
及
��������
//已处理:636缓冲区大小:640
所以额外的字节大小是不一致的,我不能只是减少一些
计算输出数组的大小时,我做错了什么?这与填充有关 AES逐块加密,每个块的长度必须为128位。传入一些不能划分为128位块的数据意味着最后一块明文必须填充到128位大小
getOutputSize
将返回您应该加密的密文的大小。请记住,明文先填充,然后加密,因此输入大小与输出大小是相同的。您可以看到这一点,因为636 mod 16=12
和636-12+16=640
。例如,它是16的最接近倍数,因为这是加密前包含的额外填充字节数
由于您在解密时使用此方法,因此数组比所需的大,因为您正在分配所需的字节
getOutputSize
可用于加密和解密,前提是您知道这是缓冲区分配的“最坏情况”。它与填充相关
AES逐块加密,每个块的长度必须为128位。传入一些不能划分为128位块的数据意味着最后一块明文必须填充到128位大小
getOutputSize
将返回您应该加密的密文的大小。请记住,明文先填充,然后加密,因此输入大小与输出大小是相同的。您可以看到这一点,因为636 mod 16=12
和636-12+16=640
。例如,它是16的最接近倍数,因为这是加密前包含的额外填充字节数
由于您在解密时使用此方法,因此数组比所需的大,因为您正在分配所需的字节getOutputSize
可用于加密和解密,前提是您知道这是缓冲区分配的“最坏情况”;DR:getOutputSize()让您知道要分配的缓冲区大小(最坏的情况),processBytes/doFinal返回的值告诉您实际使用了多少缓冲区(精确)
您正在使用PaddedBufferedBlockCipher进行解密(上面的代码默认为PKCS7填充)。getOutputSize()在实际看到最后一个块的解密数据之前无法确定输出明文的确切数量,因此返回值将是一个上限,这就是为什么processBytes/doFinal会有返回值,让您知道实际输出了多少
为简单起见,PaddedBufferedBlockCipher还忽略了所使用的特定填充方案的细节——它只假设最后一个块可能包含一些将被删除的填充
密码不会写入“exputf”结尾未使用的字节。特别是,它们将不包含填充。“奇怪字符”大概是数组初始化的零字节。TL;DR:getOutputSize()让您知道要分配的缓冲区大小(最坏的情况),processBytes/doFinal返回的值告诉您实际使用了多少缓冲区(精确)
您正在使用PaddedBufferedBlockCipher进行解密(上面的代码默认为PKCS7填充)。getOutputSize()在实际看到最后一个块的解密数据之前无法确定输出明文的确切数量,因此返回值将是一个上限,这就是为什么processBytes/doFinal会有返回值,让您知道实际输出了多少
为简单起见,PaddedBufferedBlockCipher还忽略了所使用的特定填充方案的细节——它只假设最后一个块可能包含一些将被删除的填充
密码不会写入“exputf”结尾未使用的字节。特别是,它们将不包含填充。“奇怪字符”大概是数组初始化的零字节。因为它必须返回最坏情况的值,所以给定大小的缓冲区保证足够大。因为它必须返回最坏情况的值,所以给定大小的缓冲区保证足够大。我们实际上使用PKCS7填充,我认为
PaddedBufferedBlockCipher
会处理得很好。我应该怎么做才能自动删除这些字符?我认为您使用的getOutputSize
可能是错误的。我想它只用于加密。能否验证问号是否为空字符?字节值为0。@Krystian是的,这意味着getOutputSize
仅用于加密。@KrystiangetOutputSize
不能用于确定解密的明文大小,因为只有在实际解密后才能访问填充。在您尝试之前,您无法知道明文需要多长时间。我们实际上使用了PKCS7填充,我认为PaddedBufferedBlockCipher
可以很好地处理这一问题。我应该怎么做才能自动删除这些字符?我认为您使用的getOutputSize
可能是错误的。我想是m
</body></html>��������
// Processed: 636 Buffer size: 640