【发布时间】:2020-09-29 18:18:05
【问题描述】:
我试图解密一些东西,但不明白为什么我得到空结果。我没有收到任何错误。我觉得这很奇怪。即使密钥无效,解密的垃圾也应该是无意义的字节,但不能为空。我做了最小的例子。
Aes aes = Aes.Create();
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
aes.KeySize = 128;
aes.Key = new byte[] { 0x5f, 0x4d, 0xcc, 0x3b, 0x5a, 0xa7, 0x65, 0xd6, 0x1d, 0x83, 0x27, 0xde, 0xb8, 0x82, 0xcf, 0x99 };
aes.IV = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
// Create a decryptor to perform the stream transform.
ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
// Create the streams used for decryption.
string encrypted_str_b64 = "E1UinhOTTy8Sj/IxCPEM+UNhIpTXIXnOAUtPgA35erJmvRc22gsdvIgcMZORZ2SY";
byte[] ecrypted_junk = Convert.FromBase64String(encrypted_str_b64);
string plaintext = string.Empty;
using (MemoryStream memoryStream = new MemoryStream(ecrypted_junk))
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(cryptoStream))
{
cryptoStream.FlushFinalBlock();
byte[] temp_buf = new byte[1024];
int read_bytes = cryptoStream.Read(temp_buf, 0, temp_buf.Length); //read_bytes = 0...
plaintext = srDecrypt.ReadToEnd(); //string is empty...
}
}
}
【问题讨论】:
-
FlushFinalBlock()清空流,还要写什么?如果你删除它,你会得到一个CryptographicException: Padding is invalid and cannot be removed,因为数据和密钥显然不匹配。顺便说一句,你使用了一个奇怪的结构(当然,这可能是有原因的):你首先写入一个 1024 字节的缓冲区(temp_buf),然后(如果还有一些东西)读取其余部分ReadToEnd()。因此,如果数据完全放入缓冲区,则ReadToEnd()不会读取任何内容,即使解密成功也是如此。 -
@Topaco - 用那个
buf我刚刚测试了我是否可以从流中读取一些东西......是的,我一开始遇到了Padding is invalid and cannot be removed异常,所以添加了FlushFinalBlock()以避免它,但从不知道它会清除流...我不明白data and key don't match的意思。在这种情况下我不应该得到无意义的字节输出而不是异常吗? -
Data and key don't match 应该只是表示密文是用不同的密钥生成的(否则解密会成功)。如果使用 PKCS7 填充并且解密失败(例如因为数据和密钥不匹配),通常会在最后产生与 PKCS7 不兼容的数据,从而导致观察到的异常。如果你例如解密时不要使用填充 (
PaddingMode.None) 你会得到无意义的字节。 -
@Topaco - 我认为这足以成为一个答案。做了。谢谢。
-
不客气。我已经发布了答案。
标签: c# encryption aes