Страницы

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

четверг, 11 октября 2018 г.

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

Описание проблемы: пользователи поголовно начали жаловаться на странное поведение программы (которая была написана на .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 - работает нормально.


Ответ

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

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

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