c# - 与 CryptoStream 一起使用时,嵌套 "using"会导致 .net 运行时崩溃

标签 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 运行时崩溃。这是事件日志

.NET Runtime version 2.0.50727.5485 - Fatal Execution Engine Error (000007FEE581600A) (80131506)

当然,异常(exception),只是正常

Invalid character in a Base-64 string.

我修复了它,购买删除内部使用

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 并不是真正需要的,因为 CryptoStream 只是包装了内存流和转换。如果大括号内发生错误,它将首先传播到转换的 try/catch ,然后传播到内存流。

但是考虑到这种行为仅在为 x64 构建的程序集运行并在 x64 ASP.NET 池中运行时才会发生,有人可以解释这种行为吗?当应用程序针对 x86 编译并在 32 位池中运行时,这种情况不会发生。

最佳答案

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

But can someone explain such behavior considering that this only happens when assembly runs built for x64 and runs in x64 ASP.NET pool? When application compiled for x86 and runs in 32-bit pool, it doesn't happen.

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

关于c# - 与 CryptoStream 一起使用时,嵌套 "using"会导致 .net 运行时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35589221/

相关文章:

c# - 是否可以忽略程序集 list 不匹配?

c# - 有时无法从并行运行的进程中获取输出

c# - 如何在 asp.net MVC4 中存储文件路径

c# - 在 WPF 中使用 DataTable 和 DataGrid 时出现 System.Windows.Data 错误

c# - WCF 错误 - 安全处理器无法在消息中找到安全 header

visual-studio-2010 - 在同一项目中使用 Entity Framework 3.5 和 4.0

c++ - 未解析的外部符号 CLRCreateInstance

C# 和 utf8_decode