难以理解 RijndaelManaged 加密的结果
Difficulty understanding result of RijndaelManaged encryption
在阅读了很多关于 SO 的问题和答案之后,我还没有弄清楚为什么我在下面编写的代码会产生意想不到的结果。我使用 Rfc2898DeriveBytes
class 生成一个 128 位密钥以供 RijndaelManaged
class 使用。我使用 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
属性 所以我无法检查是否有任何内容写入它。我也知道我没有在结果中预先添加盐或 IV,我还没有这样做。
仅解决您的零长度 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()
。
即使假设代码在上述更改后按预期工作,代码中还有各种其他安全问题超出了此答案的范围。
在阅读了很多关于 SO 的问题和答案之后,我还没有弄清楚为什么我在下面编写的代码会产生意想不到的结果。我使用 Rfc2898DeriveBytes
class 生成一个 128 位密钥以供 RijndaelManaged
class 使用。我使用 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
属性 所以我无法检查是否有任何内容写入它。我也知道我没有在结果中预先添加盐或 IV,我还没有这样做。
仅解决您的零长度 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()
。
即使假设代码在上述更改后按预期工作,代码中还有各种其他安全问题超出了此答案的范围。