.NET — TLS, SSL — Solving Problems

Transport Layer Security (TLS) já é amplamente utilizada como uma opção mais avançada ao Secure Sockets Layer (SSL), por fim a função de ambas é a mesma e a troca do nome se deve a uma questão “comercial” — digamos assim. O HTTPS é uma implementação do TLS quando falamos em segurança de comunicação criptografada entre aplicações web e servidores. O servidor deve ter um certificado TLS instalado, comumente chamado de SSL certificate.

Versions

Temos 3 (três) versões do SSL:

  • SSL 2.0 — se tornou deprecated em 2011 por questões de segurança e a recomendação foi usar o TLS 1.2 ou superior;
  • SSL 3.0 — se tornou deprecated em 2015 por questões de segurança.
  • 1.1: Se tornará deprecated em 2020;
  • 1.2: Lançado em 2008 e ainda em operação;
  • 1.3: Esta é a versão mais recente, definida em 2018 através da RFC 8446.

How does TLS work

Não entrarei em muitos detalhes aqui, mas se você utiliza ferramentas como o Fiddler, você vai perceber no Response da Request que estará presente o handshake ClientHello, pode parecer estranho em um primeiro momento, mas é desta forma que o browser recebe um ok do servidor, enquanto isso essa troca se torna verdadeira por conta da segurança aplicada que comumente não enxergamos da implementação do protocolo.

Problems

Algumas empresas tem feito atualizações do TLS em seus servidores, inclusive a própria Microsoft através de sua núvem Azure e estas atualizações tem impactado as aplicações com alguns erros que tem ocorrido.

Há situações em que a empresa desabilita tais protocolos no servidor, contribuindo para o aparecimento de problemas

A mensagem de erro a seguir é bem genérica, ocorre em diversas situações, até mesmo com conexões realizadas ao banco de dados SQL Server.

An existing connection was forcibly closed by the remote host

The request was aborted: Could not create SSL/TLS secure channel

Veja este caso, divulgado pela Microsoft em 2020 sobre esta mudança para quem utiliza o SDK .NET Framework para comunicação com a API do PowerBI.
Atualize a versão TLS do seu aplicativo do Power BI para TLS 1.2

.NET

Neste artigo TLS 1.2 and .NET Support: How to Avoid Connection Errors, está bem explicado as diferenças de uso do .NET Framework e como cada uma das versões permite habilitar o uso do TLS em uma determinada versão.
Tenho uma observação sobre este artigo, que o .NET Framework 4.6.1 não tem TLS 1.2 habilitado por padrão. Para mais informações pode conferir no próprio site da Microsoft sobre o assunto: How to enable TLS 1.2

Portanto, antes de mudar a configuração do servidor, pensando em trazer melhorias na segurança, verifique se suas aplicações .NET suportam esta mudança. Na GRANDE maioria dos casos a mudança de versão do .NET Framework é traumática por conta da forma com que foram construídas, tais mudanças fazem com que o software não funcione mais, ou cause incompatibilidades tornando a migração dura e dolorida.

Temos o costume de olhar a tela de erro onde tem o StackTrace completo e vendo somente as primeiros duas ou três linhas, que são as últimas execuções, mas vale reforçar aqui que no meio de toda aquela mensagem pode ter um trecho como o mostrado a seguir, este é a grande pista de que o problema está relacionado a incompatibilidade do TLS entre o servidor e a aplicação.

System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)
[SocketException (0x2746): An existing connection was forcibly closed by the remote host] System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size) +226 [IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.] System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size) +811 System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count) +48 System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest) +228 System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest) +361 System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest) +207 System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult) +806 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) +370 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) +21 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) +85 System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result) +1131 System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size) +62 System.Net.PooledStream.Write(Byte[] buffer, Int32 offset, Int32 size) +124 System.Net.ConnectStream.WriteHeaders(Boolean async) +491 [WebException: The underlying connection was closed: An unexpected error occurred on a send.] System.Net.HttpWebRequest.GetResponse() +1751 Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync(RESTCommand`1 cmd, IRetryPolicy policy, OperationContext operationContext)

Browsers

Como o TLS é um protocolo de segurança no tráfego de informações entre o cliente e o servidor, podemos dizer que o browser (navegador) ter influência e responsabilidade direta neste processo, mas algumas versões ainda possuem limitações conforme os links a seguir:

Windows Server Registry Configuration

Através do Registry Editor, você pode habilitar ou desabilitar os protocolos, SSL e TLS e suas respectivas versões seguindo os passos abaixo onde a imagem é uma parte da configuração completa a título de exemplo.

  1. Na pasta “Protocolos”, crie as pastas (botão direito New > Key) para:
    SSL 2.0
    SSL 3.0
    TLS 1.0
    TLS 1.1
    TLS 1.2
    TLS 1.3
  2. Em cada uma das pastas de cada protocolo, crie outras 2 pastas:
    Client
    Server
  3. Para cada Client, crie um novo valor botão direito “New > DWORD (32 bits) Value”
  4. Sugiro o nome “DisabledByDefault”.
  1. Para desabilitar o protocolo, altere o valor “1” e escolha a opção “Hexadecimal”.
  2. Para cada Server, crie um novo valor botão direito “New > DWORD (32 bits) Value”
  3. Sugiro o nome “Enabled”.
  1. Para desabilitar o protocolo, altere o valor “0” e escolha a opção “Hexadecimal”.

O Client e o Server tem valores invertidos para habilitar e desabilitar

Realize os passos 1 ao 10 para todos os protocolos.

Solutions

Formas de solucionar o problema, cada ponto abaixo pode ser adotado de forma independente, não precisa usar todos para solucionar o problema.

<system.web> 
<compilation debug="true" targetFramework="4.6" />
<httpRuntime targetFramework="4.6.2" />
</system.web>
public class Global : System.Web.HttpApplication 
{
void Application_Start(object sender, EventArgs e)
{
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
}
}

Repense a forma com que a arquitetura do seu sistema, seja um monolito ou não, foi pensada, idealizada e projetada para que uma atualização do .NET Framework não seja um Épico sem fim

Originally published at http://alextochetto.com on November 6, 2020.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store