前言
有个项目之前是在.NET Framework 4.5框架开发的,近期使用.NET 6重构了,其中需要使用DES3加解密,发现了一个很奇怪的问题:解密后的数据被截取并以\0\0结尾,写个文章记录一下,以防以后忘记了。
环境
运行环境:.NET 6
开发环境:VS2022 17.1
问题
使用同一个解密程序,在.NET Framework 4.5 和.NET 6得到的结果不一样,
"{\"22028\":{\"ReqTimestamp\":1661414260\0\0\0\0\0\0\0\0" //.NET 6
"{\"22028\":{\"ReqTimestamp\":1661414260952}}\0\0\0" //.NET Framework 4.5
可以看出在.NET 6下解密后数据会被截取一部分,被\0\0替代了,但在.NET Framework 4.5 下是正常的。这是怎么回事呢,经过一番Google,有人已经向官方提了这个issue,在这个讨论贴 下也有相关的解释,即:从 .NET 6 开始,当Stream.Read或Stream.ReadAsync在具有长度缓冲区的受影响流类型之一上调用时N,操作在以下情况下完成:
1、从流中读取了至少一个字节,或者
2、它们包装的底层流从对其读取的调用中返回 0,表示没有更多数据可用。
此外,当使用长度为 0 的缓冲区调用Stream.Reador时Stream.ReadAsync,一旦使用非零缓冲区的调用成功,操作就会成功。
详细可见官方说明
可以改成这样:
public static string Des3DecodeCBC(byte[] key, byte[] iv, byte[] data)
{
try
{
using (MemoryStream stream = new MemoryStream(data))
{
using (var tripleDES = TripleDES.Create())
{
using (CryptoStream cStream = new CryptoStream(stream,
tripleDES.CreateDecryptor(KEY, IV),
CryptoStreamMode.Read))
{
using (StreamReader sReader = new StreamReader(cStream))
{
return sReader.ReadToEnd();
}
}
}
}
}
catch (CryptographicException e)
{
Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
return null;
}
}
结语
其实只是使用方法不一样了,不能使用之前的那种方式。.NET 6使用的不多,遇到问题很难找到类似的解决方案,查看官方文档是比较好的方式,还可以查看github上的讨论,也许能找到答案。
今天遇到这个问题,折腾了半天,记录一下,以防下次忘记了。