Страницы

Поиск по вопросам

воскресенье, 8 декабря 2019 г.

Что именно разработчики .NET 4.6.2 изменили в SslStream помимо SSL3?

#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 транспорта ОС.

Комментариев нет:

Отправить комментарий