【发布时间】:2013-11-29 09:51:42
【问题描述】:
我正在尝试实现内存中的 AESManaged 加密/解密。这里的代码就是基于这个:
Encrypting/Decrypting large files (.NET)
加密部分似乎起作用了,也就是说,没有例外。但是解密部分会抛出“索引超出数组范围”的错误。
在早期的代码中,转换是这样初始化的:
aes = new AesManaged();
aes.BlockSize = aes.LegalBlockSizes[0].MaxSize;
aes.KeySize = aes.LegalKeySizes[0].MaxSize;
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(Key, salt, 1);
aes.Key = key.GetBytes(aes.KeySize / 8);
aes.IV = key.GetBytes(aes.BlockSize / 8);
aes.Mode = CipherMode.CBC;
transform = aes.CreateDecryptor(aes.Key, aes.IV);
void AESDecrypt(ref byte[] inB)
{
using (MemoryStream destination = new MemoryStream(inB, 0, inB.Length))
{
using (CryptoStream cryptoStream = new CryptoStream(destination, transform, CryptoStreamMode.Write))
{
try
{
using (MemoryStream source = new MemoryStream(inB, 0, inB.Length))
{
if (source.CanWrite==true)
{
source.Write(inB, 0, inB.Length);
source.Flush(); //<<inB is unchanged by the write
}
}
}
catch (CryptographicException exception)
{
if (exception.Message == "Padding is invalid and cannot be removed.")
throw new ApplicationException("Universal Microsoft Cryptographic Exception (Not to be believed!)", exception);
else
throw;
}
}
} <====At this point I get an IndexOutofBounds exception.
}
}
似乎有问题的行可能是: 使用 (CryptoStream cryptoStream = new CryptoStream(destination, transform, CryptoStreamMode.Write))
【问题讨论】:
-
你试过什么?喜欢调试你的自己的代码吗?
-
是的,不知道你在做什么。
-
if (source.CanWrite==true)。如果 CanWrite 为假怎么办?那你什么都不写?如果您仍然不处理此案,最好让它失败。 -
关于您的实际问题,您发送的数据是错误的。错误的密钥、IV 或字节。所以也要显示加密。顺便说一句,任何人都可以在没有解密通知的情况下修改您的加密数据。您应该使用经过身份验证的加密(AES-GCM 非常安全)。
-
另外,IV 对于每个加密应该是唯一的。使用 CBC 很幸运,但对于其他模式,不同数据的相同 IV 会 100% 破坏安全性。
标签: c# memorystream cryptostream