#c_sharp #net #ssl #tls
Описание проблемы: пользователи поголовно начали жаловаться на странное поведение программы (которая была написана на .NET 4.5) после автоматического обновления Windows. Начал разбираться, тестировать. Воспроизвел проблему у себя на .NET 4.6.2. Оказывается транспорт SslStream начиная с .NET 4.6 поменял свое поведение. Причем непонятно в каком месте. Взял сторонний транспорт (Chilkat), сравнил - везде получается одинаковые параметры, TLS 1.0, Cipher - Aes128, Hash - Sha1, одинаковые байты идущие через соединение... Но! - Chilkat отрабатывает нормально, а SslStream рвет соединение на ReadAsync с исключением: IOException, сбой операции дешифрования. Журналы ошибок Windows пустые. Вопрос: что конкретно изменилось в реализации? p.s. Switch.System.Net.DontEnableSchUseStrongCrypto=true в appconfig не помогает, поведение не меняется. Update: Посмотрел локальные исключения, вот что всплыло: System.ComponentModel.Win32Exception (0x80004005): Не удается установить связь с локальной системой безопасности. Погуглил, нашел что это связано с лицензией на Windows. Хоть убейте не понимаю чем связана неактивированная тестовая Windows с работоспособностью SslStream. Клиентов ведь не заставишь поголовно покупать лицензии... Часть синхронного стека вызовов: System.dll!System.Net.Security._SslStream.ProcessReadErrorCode(System.Net.SecurityStatus errorCode = {неизвестно}, byte[] buffer = {неизвестно}, int offset = {неизвестно}, int count = {неизвестно}, System.Net.AsyncProtocolRequest asyncRequest = {неизвестно}, byte[] extraBuffer = {неизвестно}) System.dll!System.Net.Security._SslStream.ProcessFrameBody(int readBytes = {неизвестно}, byte[] buffer = {неизвестно}, int offset = {неизвестно}, int count = {неизвестно}, System.Net.AsyncProtocolRequest asyncRequest = {неизвестно}) System.dll!System.Net.Security._SslStream.StartFrameHeader(byte[] buffer = {неизвестно}, int offset = {неизвестно}, int count = {неизвестно}, System.Net.AsyncProtocolRequest asyncRequest = {неизвестно}) System.dll!System.Net.Security._SslStream.StartReading(byte[] buffer = {неизвестно}, int offset = {неизвестно}, int count = {неизвестно}, System.Net.AsyncProtocolRequest asyncRequest = {неизвестно}) System.dll!System.Net.Security._SslStream.ProcessRead(byte[] buffer = {неизвестно}, int offset = {неизвестно}, int count = {неизвестно}, System.Net.AsyncProtocolRequest asyncRequest = {неизвестно}) System.dll!System.Net.Security._SslStream.Read(byte[] buffer = {неизвестно}, int offset = {неизвестно}, int count = {неизвестно}) > Application.exe!d__a.MoveNext() Update2: Провел ряд тестов в процессе воспроизведения проблемы для публичного обозрения - по предварительным данным виноват Cipher = Aes128, тот же Aes256 - работает нормально.
Ответы
Ответ 1
Для .NET 4.+ и x64 разрядных ОС, глобальный вариант: Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319] "SchSendAuxRecord"=dword:00000000 Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319] "SchSendAuxRecord"=dword:00000000 Для .NET 2.+ и x64 разрядных ОС, глобальный вариант: Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v2.0.50727] "SchSendAuxRecord"=dword:00000000 Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v2.0.50727] "SchSendAuxRecord"=dword:00000000 Действует сразу, перезапуск ОС не требуется. Использовать только в крайнем случае!!! Выключение этой структуры связано с большими рисками по отношению к старым версиям SSL\TLS транспорта ОС.
Комментариев нет:
Отправить комментарий