如何解决有弹性的城堡添加额外的填充块
我已经使用BounyCastle v1.8.6 .net核心实现了AES 128 CBC加密,当我尝试加密长度为16字节的数据时,该问题又增加了一个包含数据填充的16字节(我猜是)。我不知道为什么要加上这个。知道默认的c#实现不能做到这一点
以十六进制格式作为字符串的数据示例 6752b87027fc7728fbe4ec2f0d76da75 => EE93F245FCDB928BF8E3012C9E5150EDA1B876A6D790CFC69C2F129215B3C938
如果要加密的数据是32、64、128等,也会发生这种情况
代码:
int DefaultBlockSize = 16;
public byte[] Encrypt(byte[] plainBytes,byte[] key,byte[] iv = null)
{
iv ??= new byte[DefaultBlockSize] ;
AesEngine engine = new AesEngine();
CbcBlockCipher blockCipher = new CbcBlockCipher(engine);
IBlockCipherPadding padding = new ZeroBytePadding();
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(blockCipher,padding);
KeyParameter keyParam = new KeyParameter(key);
ParametersWithIV keyParamWithIV = new ParametersWithIV(keyParam,iv,DefaultBlockSize);
// Encrypt
cipher.Init(true,keyParamWithIV);
byte[] outputBytes = new byte[cipher.GetOutputSize(plainBytes.Length)];
int length = cipher.ProcessBytes(plainBytes,outputBytes,0);
cipher.DoFinal(outputBytes,length);
return outputBytes ;
}
有什么办法解决这个问题吗?
解决方法
发布的代码适用Zero padding。零填充有多种变体。如果明文长度是already
块大小的整数倍(例如,使用BC的变体),则一个填充完整的块,另一个则不填充(例如,使用.NET的变体),另请参见{{ 3}},零填充部分的最后一句话。
BC和.NET变体之间的另一个区别是BC变体在解密过程中删除了填充,而.NET变体没有。
这种矛盾是零填充的缺点。另一个缺点是无法区分终止明文0x00字节和填充0x00字节,因为零填充不包含有关填充字节数的信息。
由于这种不可靠的PKCS7填充更好:它在here(第10.3节,注释2)中进行了严格定义(即没有不同的变体),并且包含有关填充字节数的信息,因此可以将它们与纯文本字节区分开。
BouncyCastle没有提供在不同的零填充变体之间进行选择的选项。它仅提供上述变体。因此,要将BouncyCastle与.NET变体一起使用,必须自己实现:首先,必须将PaddedBufferedBlockCipher
替换为BufferedBlockCipher
,这仅意味着不使用(BouncyCastle)填充。其次,.NET变体必须以相对简单的方法来实现:如果明文的长度不是块长度的整数倍,则使用0x00值进行填充,直到满足此条件。该方法然后在加密之前应用于纯文本。由于.NET变体不会在解密过程中删除“零填充”,因此解密只需要第一部分。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。