Вложенное "использование" приводит к сбою.net среды выполнения при использовании с CryptoStream

У нас есть этот простой код, который был преобразован из vb.net, где он не был создан с использованием using/end using, Во время конвертации мы использовали 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)

И исключение, конечно, просто нормально

Недопустимый символ в строке 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 Runtime, поэтому работает нормально. Также размещение try/catch-rethrow где это было раньше, предотвратило бы и такой сбой.

Я подозреваю, что это имеет отношение к вложенным using, внутренний using на самом деле не нужно, потому что CryptoStream просто оборачивает поток памяти и преобразование. И если ошибка происходит внутри фигурных скобок, она будет распространена на try/catch трансформации сначала, а затем поток памяти.

Но может ли кто-нибудь объяснить такое поведение, учитывая, что это происходит только тогда, когда сборка выполняется для x64 и выполняется в пуле ASP.NET x64? Когда приложение скомпилировано для x86 и работает в 32-битном пуле, этого не происходит.

1 ответ

Решение

Это, несомненно, ошибка во время выполнения. Поскольку вы используете крайне старую версию среды выполнения, мой совет - обновить.

Но может ли кто-нибудь объяснить такое поведение, учитывая, что это происходит только тогда, когда сборка выполняется для x64 и выполняется в пуле ASP.NET x64? Когда приложение скомпилировано для x86 и работает в 32-битном пуле, этого не происходит.

Дрожания x64 и x86 были совершенно разными кодовыми базами в этой версии. Ошибка, достаточно серьезная, чтобы вызвать сбой среды выполнения, включающий странные ошибки кодагена во вложенных блоках try-finally, почти наверняка будет уникальной для конкретного джиттера.

Другие вопросы по тегам