难以理解RijndaelManaged加密的结果

时间:2015-09-08 04:44:31

标签: c# encryption aes

在阅读了很多关于SO的问题和答案之后,我还没弄清楚为什么我在下面编写的代码会产生意想不到的结果。我使用Rfc2898DeriveBytes类生成一个128位密钥,用于RijndaelManaged类。我使用GenerateIV()生成IV。我在这里做错了吗?我所看到的许多代码示例都非常恰到好处。

string text = "TEXT TO ENCRYPT";
string key = "MY_KEY";
byte[] saltRaw = BitConverter.GetBytes((long)text.Length);
Rfc2898DeriveBytes deriver = new Rfc2898DeriveBytes(key, saltRaw);
byte[] keyRaw = deriver.GetBytes(32);

RijndaelManaged rij = new RijndaelManaged();
rij.Key = keyRaw;
rij.GenerateIV();

ICryptoTransform encryptor = rij.CreateEncryptor(rij.Key, rij.IV);
MemoryStream sMemory = new MemoryStream();
CryptoStream sCrypt = new CryptoStream(sMemory, encryptor, CryptoStreamMode.Write);
StreamWriter sWriter = new StreamWriter(sCrypt);
sWriter.Write(text);
byte[] r = sMemory.ToArray();

sWriter.Dispose();
sCrypt.Dispose();
sMemory.Dispose();
encryptor.Dispose();
return r; // length of r is 0.

这里的问题是byte[] r的长度为0,因此没有任何内容写入内存流。 CryptoStream没有实现length属性,所以我无法检查是否有任何内容被写入。我也知道我没有预先准备Salt或IV预测结果,我还没有这样做。

1 个答案:

答案 0 :(得分:1)

仅解决您的零长r问题,这是由于StreamWriter内的缓冲,所以当您尝试获取MemoryStream的内容时,实际上什么都没有已被写入。

byte[] r;
using (var sMemory = new MemoryStream())
{
    using (var sCrypt = new CryptoStream(sMemory, encryptor, CryptoStreamMode.Write))
    {
        using (var sWriter = new StreamWriter(sCrypt))
        {
            sWriter.Write(text);
        }
    }
    r = sMemory.ToArray();
}

我强烈建议您使用上面的using()块,而不是显式调用Dispose(),因为这样可以确保即使在异常的情况下也能正确处理,并且还有助于避免在处置后使用对象,或者根本没有打电话给Dispose()

即使假设代码在上述更改后按预期工作,代码中还存在各种其他安全问题,超出了本答案的范围。