与CryptoStream一起使用时嵌套的“使用”崩溃.net运行时

时间:2016-02-23 22:07:40

标签: c# .net-3.5 .net-runtime

我们有这个简单的代码,它是从vb.net转换而来的,它不是使用using/end using构建的。在转换过程中,我们在c#中使用了using

using (var memStream = new MemoryStream() { Position = 0L })
using (ICryptoTransform cryptoTransfrom = (new TripleDESCryptoServiceProvider()).CreateDecryptor(_key, _iv))
{
    using (var cryptStream = new CryptoStream(memStream, cryptoTransfrom, CryptoStreamMode.Write))
    {
        // <-- here used to be try
        string convertedValue = ConvertHexToDec(value);
        byte[] decryptBytes = Convert.FromBase64String(convertedValue); //<-- Error line
        // <-- here used to be catch/throw
        cryptStream.Write(decryptBytes, 0, decryptBytes.Length);
        cryptStream.FlushFinalBlock();
        cryptStream.Close();
    }
    decodedVal = Encoding.ASCII.GetString(memStream.ToArray());
}

try/catch周围有Convert.FromBase64String(convertedValue)(见评论)。我们没有意识到的是,value有时会以普通的,非base64编码的值出现。因此,当未编码的值达到“错误行”时 - try/catch做了重新抛出的业务。但是,当你查看上面的代码时,当这样的值导致该行的异常时 - .NET Runtime崩溃。这是事件日志

  

.NET Runtime版本2.0.50727.5485 - 致命执行引擎错误(000007FEE581600A)(80131506)

例外,cource,只是正常

  

Base-64字符串中的字符无效。

我修好了购买删除内部using

using (var memStream = new MemoryStream() { Position = 0L })
using (ICryptoTransform cryptoTransfrom = (new TripleDESCryptoServiceProvider()).CreateDecryptor(_key, _iv))
{
    var cryptStream = new CryptoStream(memStream, cryptoTransfrom, CryptoStreamMode.Write);
    string convertedValue = ConvertHexToDec(value);
    byte[] decryptBytes = Convert.FromBase64String(convertedValue); //<-- Error line      
    cryptStream.Write(decryptBytes, 0, decryptBytes.Length);
    cryptStream.FlushFinalBlock();
    cryptStream.Close();
    decodedVal = Encoding.ASCII.GetString(memStream.ToArray());
}

现在,错误,当然仍然发生,但它不会崩溃.NET运行时,因此行为正常。此外,将try/catch-rethrow放在之前的位置也可以防止此类崩溃。

我怀疑,它与嵌套using有关。内部using并不是真正需要的,因为CryptoStream只是包装内存流和转换。如果大括号内发生错误,它将首先传播到转换的try/catch,然后传播到内存流。

但有人可以解释这种行为,因为这只会在为x64构建的程序集运行并在x64 ASP.NET池中运行时才会发生吗?当为x86编译的应用程序并在32位池中运行时,它不会发生。

1 个答案:

答案 0 :(得分:3)

毫无疑问,它是运行时中的一个错误。由于您使用的是非常旧版本的运行时,我的建议是升级。

  

但有人可以解释这种行为,因为这只会在为x64构建的程序集运行并在x64 ASP.NET池中运行时才会发生吗?当为x86编译的应用程序并在32位池中运行时,它不会发生。

x64和x86抖动在该版本中是完全不同的代码库。一个严重到足以使嵌套的try-finally块中出现奇怪的codegen错误的运行时崩溃的错误几乎肯定是特定抖动所特有的。