我正在尝试使用带有CBC模式的AES算法加密我的数据。出于这个原因,我使用.Net Library'Bouncy Castle'。我没有加密的背景,所以我试图以一种简单的方式使用它。这是我的加密代码
public byte[] encrypt(byte[] key, byte[] iv,byte[] data)
{
IBlockCipher engine=new AesFastEngine();
KeyParameter keyParam = new KeyParameter(key);
CbcBlockCipher cipher = new CbcBlockCipher(engine);
ICipherParameters parameters = new ParametersWithIV(keyParam, iv);
byte[] output=new byte[16+data.Length];
cipher.Init(true, parameters);
cipher.ProcessBlock(data, 0, output, data.Length);
//process output
byte[] cipherArray = new byte[data.Length];
/*
int k=0;
for (int i = 0; i < output.Length; i++)
{
if (output[i]!= 0)
{
cipherArray[k++] = output[i];
}
}
*/
return cipherArray;
}
当我尝试的输入不是16的乘法时,我得到一个例外。当我用右边的数字(16长度%16)向右填充数组时,我可以得到一个结果。但结果对我来说也是一个问题。它给了我这样的结果:
[0][0][0][0[111][22][33][44][66][77][33][12][32][23][0][0][0][0][0]
左右两边都是零。
我认为这可能与我使用ProcessBlock(data, 0, output, data.Length)
功能有关。我使用它假设输出将是我的加密文本,但似乎输出应该长于输入长度。由于我没有关于此功能的文档,我可能以错误的方式使用它。任何帮助将不胜感激
答案 0 :(得分:4)
Bouncy Castle会为你做填充,开始你需要设置你的cihper:
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CbcBlockCipher(engine), new Pkcs7Padding());
要使其余代码工作,需要使用cipher.GetOutputSize(data.Length)
ProcessBytes
和DoFinal
,以便正确添加填充。
byte[] output = new byte[cipher.GetOutputSize(data.Length)];
int len = cipher.ProcessBytes(data, 0, data.Length, output, 0);
cipher.DoFinal(output, len);
我有一个使用AES-GCM in Bouncy Castle on CodeReview
的简单示例AES-GCM添加了经过身份验证的加密,但使用api的基本原则是相同的。
我还有一个高级加密框架的C#端口Kecyzar,我使用Bouncy Castle作为后端,虽然这是一个更难的例子,但是使用AES设置了抽象加密代码SymmetricStream -CBC在BouncyAesKey
答案 1 :(得分:3)
通常会使用标准填充算法来确保明文数据与密码的块大小对齐。
您目前正在手动编码zero padding。这不是一个很好的选择,因为它禁止以零字节结尾的原始数据 - 你如何区分它与填充?
我建议您使用标准填充,例如PKCS #7 padding。请注意,这通常被称为“ PKCS#5 padding ”,因为它们非常相似。
您可能希望参考其他SO问题 - Encrypt/Decrypt using Bouncy Castle in C# - 有关使用标准填充的示例。