У нас есть этот простой код, который был преобразован с vb.net, где он не был сконструирован с использованием using/end using
. Во время преобразования мы использовали using
в C#.Вложенные «с помощью» сбоев .net runtime при использовании с CryptoStream
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 время выполнения версия 2.0.50727.5485 - Fatal Error Execution Engine (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, поэтому действует нормально. Кроме того, размещение try/catch-rethrow
, где оно было раньше, также предотвратило бы такой крах.
Я подозреваю, что это как-то связано с вложенными using
. Внутренний using
не нужен, потому что CryptoStream
просто обертывает поток памяти и преобразование. И если ошибка возникает внутри фигурных скобок, она будет распространяться до try/catch
преобразования сначала, а затем потока памяти.
Но может ли кто-нибудь объяснить такое поведение, учитывая, что это происходит только тогда, когда сборки выполняются для x64 и запускаются в пуле x64 ASP.NET? Когда приложение скомпилировано для x86 и запускается в 32-битном пуле, этого не происходит.
Куда он падает? – Valentin
Попробуйте переместить 'decodedVal = Encoding.ASCII.GetString (memStream.ToArray());' write after 'cryptStream.FlushFinalBlock();'. –
Что значит «действует нормально»? 'using' не обрабатывает каких-либо исключенных исключений - он просто гарантирует, что одноразовый компонент будет удален, есть ли исключение или нет. –