SecurityProtocol padrão no .NET 4.5

253

Qual é o protocolo de segurança padrão para comunicação com servidores que suportam até TLS 1.2? Vai .NETpor padrão, escolha a maior protocolo de segurança suportado no lado do servidor ou eu tenho que adicionar explicitamente esta linha de código:

System.Net.ServicePointManager.SecurityProtocol = 
SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

Existe uma maneira de alterar esse padrão, além de uma alteração de código?

Por fim, suporta .NET 4.0apenas até TLS 1.0? ou seja, eu tenho que atualizar os projetos do cliente para 4.5 para dar suporte TLS 1.2.

Minha motivação é remover o suporte SSLv3no lado do cliente, mesmo que o servidor o suporte (eu já tenho um script do PowerShell para desativá-lo no registro da máquina) e oferecer suporte ao protocolo TLS mais alto suportado pelo servidor.

Atualização: Olhando para a ServicePointManagerclasse, .NET 4.0não vejo valores enumerados para TLS 1.0e 1.1. Nos dois .NET 4.0/4.5, o padrão é SecurityProtocolType.Tls|SecurityProtocolType.Ssl3. Esperamos que esse padrão não seja quebrado ao desativar SSLv3o registro.

No entanto, decidi que tenho de atualizar todos os aplicativos .NET 4.5e adicioná- SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;los explicitamente de qualquer maneira a todos os códigos de inicialização de todos os aplicativos.

Isso fará solicitações de saída para várias APIs e serviços para não fazer o downgrade SSLv3e deve selecionar o nível mais alto de TLS.

Essa abordagem parece razoável ou exagerada? Eu tenho muitos aplicativos para atualizar e quero protegê-los no futuro, pois ouvi dizer que TLS 1.0talvez sejam preteridos no futuro próximo por alguns fornecedores.

Como cliente que faz solicitações de saída para APIs, a desativação do SSL3 no registro tem efeito na estrutura .NET? Vejo por padrão que o TLS 1.1 e 1.2 não estão habilitados, precisamos habilitá-lo através do registro? RE http://support.microsoft.com/kb/245030 .

Após um pouco de investigação, acredito que as configurações do registro não terão efeito, pois se aplicam ao IIS (subchave do servidor) e navegadores (subchave do cliente).

Desculpe, este post se transformou em várias perguntas, seguido de respostas "talvez".

Luke Hutton
fonte
FYI: Últimas práticas recomendadas em relação ao TLS: docs.microsoft.com/en-us/dotnet/framework/network-programming/…
JohnLBevan
Para aqueles que querem ver a melhor resposta para isso, classifique por votos!
Navule
1
Perguntas e respostas relacionadas ao SO: stackoverflow.com/questions/41618766/… Os leitores devem observar que essa pergunta está envelhecendo e que novas recomendações estão em vigor a partir de 2020.
Sem reembolsos Sem retornos

Respostas:

280

Alguns dos que deixaram comentários comentaram que definir System.Net.ServicePointManager.SecurityProtocolvalores específicos significa que seu aplicativo não poderá tirar proveito de versões futuras do TLS que podem se tornar os valores padrão em futuras atualizações do .NET. Em vez de especificar uma lista fixa de protocolos, você pode ativar ou desativar os protocolos que você conhece e se preocupa, deixando os outros como estão.

Para ativar o TLS 1.1 e 1.2 sem afetar outros protocolos:

System.Net.ServicePointManager.SecurityProtocol |= 
    SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

Observe o uso de |=para ativar essas bandeiras sem desativar outras.

Para desativar o SSL3 sem afetar outros protocolos:

System.Net.ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Ssl3;
Scott
fonte
6
Esta é realmente a resposta correta. A resposta aceita garantirá que seu aplicativo sempre desative novas versões do TLS, a menos que você volte e atualize seu código.
Connor
5
@ Gertsen Não, é um bit a bit ou, portanto, apenas ativa os bits apropriados se estiverem desativados. Se esses bits já estiverem ativados, nenhuma alteração ocorrerá.
Scott
3
E o equivalente do PowerShell é [Net.ServicePointManager]::SecurityProtocol = ([Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls12) Invoke-RestMethod, que depende das mesmas bibliotecas de estrutura .NET subjacentes.
Martin Hollingsworth
15
Como ninguém está falando sobre onde colocar esse código, eu o coloquei no Application_Start do Global.asax.cs para meu aplicativo ASP.NET MVC. Eu estava procurando como enviar minhas solicitações SMTP pelo TLS1.2 e NÃO pelo TLS1.0. Eu também adicionei & = ~ SecurityProtocolType.Tls para desligar TLS 1.0
Greg Veres
2
No VB, o equivalente éNet.ServicePointManager.SecurityProtocol = Net.ServicePointManager.SecurityProtocol OR Net.SecurityProtocolType.Tls12 OR Net.SecurityProtocolType.Tls12
Codespaced 14/02/19
188

O padrão System.Net.ServicePointManager.SecurityProtocolno .NET 4.0/4.5é SecurityProtocolType.Tls|SecurityProtocolType.Ssl3.

.NET 4.0suporta até TLS 1.0enquanto .NET 4.5suporta atéTLS 1.2

No entanto, um direcionamento de aplicativo .NET 4.0ainda pode suportar até TLS 1.2se .NET 4.5estiver instalado no mesmo ambiente. .NET 4.5instala sobre .NET 4.0, substituindo System.dll.

Eu verifiquei isso observando o protocolo de segurança correto definido no tráfego com fiddler4e definindo manualmente os valores enumerados em um .NET 4.0projeto:

ServicePointManager.SecurityProtocol = (SecurityProtocolType)192 |
(SecurityProtocolType)768 | (SecurityProtocolType)3072;

Referência:

namespace System.Net
{
    [System.Flags]
    public enum SecurityProtocolType
    {
       Ssl3 = 48,
       Tls = 192,
       Tls11 = 768,
       Tls12 = 3072,
    }
}

Se você tentar o hack em um ambiente com o ONLY .NET 4.0instalado, você receberá a exceção:

Exceção sem tratamento: System.NotSupportedException: o protocolo de segurança solicitado não é suportado. em System.Net.ServicePointManager.set_SecurityProtocol (SecurityProtocolType v alue)

No entanto, eu não recomendaria esse "hack", pois um patch futuro etc. poderá quebrá-lo. *

Portanto, decidi que o melhor caminho para remover o suporte SSLv3é:

  1. Atualize todos os aplicativos para .NET 4.5
  2. Adicione o seguinte ao código de inicialização automática para substituir o padrão e o futuro:

    System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

* Alguém me corrija se esse hack estiver errado, mas testes iniciais eu vejo que funcionam

Luke Hutton
fonte
6
Por favor, veja imperialviolet.org/2014/12/08/poodleagain.html "Parece um bom momento para reiterar que tudo menos que o TLS 1.2 com um conjunto de cifras AEAD está criptograficamente quebrado".
Neil
3
@Mathew, visualizando o código-fonte de ServicePointManager.csver referencesource.microsoft.com/#System/net/System/Net/...
Luke Hutton
12
Eu continuo vendo as pessoas reivindicarem os .NET 4.5padrões do Tls12 - mas como você colocou aqui, isso não acontece. Dá-lhe a opção de usá-lo paraSecurityProtocol
Don Cheadle
17
Não vou recusar esta resposta, pois ela fornece muitas informações úteis, mas implementar uma versão de protocolo codificada não é uma boa ideia, pois restringe o aplicativo a usar a melhor criptografia disponível e pode resultar em problemas de segurança no futuro. As alterações do registro para alterar o comportamento padrão do .Net para realmente oferecer suporte a protocolos modernos são muito preferíveis. (É, no entanto, notar a alteração do Registro também desativa SSL v3.)
AJ Henderson
6
No FW 4.6 e 4.7, o padrão é agora SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12como por support.microsoft.com/en-us/help/3069494/...
Ian Kemp
68

Você pode substituir o comportamento padrão no seguinte registro:

Key  : HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 
Value: SchUseStrongCrypto
Type: REG_DWORD
Data : 1

e

Key  : HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319
Value: SchUseStrongCrypto
Type: REG_DWORD
Data : 1

Para detalhes, consulte a implementação deServicePointManager .

Jiri Mares
fonte
Obrigado, eu não sabia disso. Eu vou testar. Eu criei um script do powershel para defini-lo: gist.github.com/lukehutton/ab80d207172a923401b1
Luke Hutton
6
Alterar o registro não parece ser uma boa solução. Se o aplicativo desejar dar suporte ao TLS1, ele deverá considerar o assunto. Não é o ambiente em execução. Caso contrário, isso pode prejudicar outros aplicativos ou prejudicar a implantação e a atualização de seu aplicativo.
21416 Mikhail G #
13
@MikhailG muito pelo contrário. A alteração do registro é o método preferencial. O SChannel fornece uma abstração da negociação subjacente e você deseja que seu aplicativo use qualquer que seja o nível de segurança mais alto suportado. Limitá-lo artificialmente em software resulta em problemas futuros quando novos protocolos forem lançados e seu software não puder usá-los. Seria bom se houvesse uma opção para dizer usar apenas melhor que um determinado protocolo em software, mas não há opção para isso sem também impedir que versões futuras funcionem. O fez desativar SSL v3 com que a mudança embora ..
AJ Henderson
13
Linha de comando: reg add HKLM\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 /v SchUseStrongCrypto /t REG_DWORD /d 1 /reg:64(e / ou /reg:32)
Kevin Smyth
7
@ MikhailG: A configuração do registro não impede que os aplicativos suportem protocolos mais antigos. Apenas altera os padrões (que incluem tls 1.0 a partir de agora). Além disso, o comportamento padrão no .Net 4.6+ é usar criptografia forte; nesse caso, essa entrada do registro seria útil apenas como um meio de desativar criptografia forte.
Brian
51

Crie um arquivo de texto com uma .regextensão e o seguinte conteúdo:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319]
"SchUseStrongCrypto"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319]
"SchUseStrongCrypto"=dword:00000001

Ou faça o download da seguinte fonte:

https://tls1test.salesforce.com/s/NET40-Enable-TLS-1_2.reg

Clique duas vezes para instalar ...

dana
fonte
3
O link que você forneceu parece ter problemas com o certificado SSL.
NathanAldenSr
Mesmo quando adiciono essas chaves do Registro, ainda tenho esse problema. Qualquer ideia ?
Samidjo 13/07/16
@ Samidjo - Qual versão do .NET você está usando? A resposta de Luke entra em muito mais detalhes que a minha, mas parece que você precisa pelo menos do .NET 4.5 instalado. Além disso, se você acabou de fazer a alteração, pode ser necessário reciclar o pool de aplicativos. Estes são o tipo de suposições, assim, sem mais detalhes eu poderia ser capaz de ajudar muito mais :)
dana
2
Um patch recentemente aplicado support.microsoft.com/en-us/help/4019114/… para um servidor causou falha no aplicativo .net 4.5.2 nas solicitações https REST. Essas chaves resolveram o nosso problema.
Kleinux
21

Descobri que, quando especifico apenas o TLS 1.2, ele ainda será negociado para 1.1. System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

Especifiquei isso no método de inicialização Global.asax para meu aplicativo da web .net 4.5.

Jim
fonte
2
Qual é o protocolo de segurança suportado no servidor? Acredito que também é fator aqui e pode ser 1,1 é o mais recente no servidor. www.passionatecoder.ca
Ehsan
14
Promovido porque esta é a única resposta que indica ONDE colocar a linha de código que é a solução.
jgerman
1
O cliente (por exemplo, seu C # WebClient) e o servidor (servidor de API que você está chamando) negociarão para usar o protocolo mais alto que ambos suportam. Portanto, se seus suportes de cliente TLS 1.2, mas o servidor só TLS 1.1 - o cliente usará TLS 1.1 (a menos que você remover TLS 1.1 do seu cliente - caso em que eles não podem encontrar um protocolo mutuamente suportado, e Cliente erro)
Don Cheadle
Teve que adicionar utilizando System.Net em global.asax.cs
Patrick
16

O código a seguir será:

  • protocolos habilitados para impressão
  • imprimir protocolos disponíveis
  • ative o TLS1.2 se a plataforma suportar e se não estiver ativado para começar
  • desativar SSL3 se estiver ativado
  • resultado final de impressão

Constantes:

  • 48 é SSL3
  • 192 é TLS1
  • 768 é TLS1.1
  • 3072 é TLS1.2

Outros protocolos não serão afetados. Isso torna isso compatível com protocolos futuros (Tls1.3, etc).

Código

// print initial status
    Console.WriteLine("Runtime: " + System.Diagnostics.FileVersionInfo.GetVersionInfo(typeof(int).Assembly.Location).ProductVersion);
    Console.WriteLine("Enabled protocols:   " + ServicePointManager.SecurityProtocol);
    Console.WriteLine("Available protocols: ");
    Boolean platformSupportsTls12 = false;
    foreach (SecurityProtocolType protocol in Enum.GetValues(typeof(SecurityProtocolType))) {                
        Console.WriteLine(protocol.GetHashCode());
        if (protocol.GetHashCode() == 3072){
            platformSupportsTls12 = true;
        }
    }
    Console.WriteLine("Is Tls12 enabled: " + ServicePointManager.SecurityProtocol.HasFlag((SecurityProtocolType)3072));    


// enable Tls12, if possible
    if (!ServicePointManager.SecurityProtocol.HasFlag((SecurityProtocolType)3072)){
        if (platformSupportsTls12){
            Console.WriteLine("Platform supports Tls12, but it is not enabled. Enabling it now.");
            ServicePointManager.SecurityProtocol |= (SecurityProtocolType)3072;
        } else {
            Console.WriteLine("Platform does not supports Tls12.");
        }
    }

// disable ssl3
   if (ServicePointManager.SecurityProtocol.HasFlag(SecurityProtocolType.Ssl3)) { 
      Console.WriteLine("Ssl3SSL3 is enabled. Disabling it now.");
      // disable SSL3. Has no negative impact if SSL3 is already disabled. The enclosing "if" if just for illustration.
      System.Net.ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Ssl3;                      
   }
    Console.WriteLine("Enabled protocols:   " + ServicePointManager.SecurityProtocol);

Resultado

Runtime: 4.7.2114.0
Enabled protocols:   Ssl3, Tls
Available protocols: 
0
48
192
768
3072
Is Tls12 enabled: False
Platform supports Tls12, but it is not enabled. Enabling it now.
Ssl3 is enabled. Disabling it now.
Enabled protocols:   Tls, Tls12
gerasoras
fonte
14

Eu tive o problema quando meu cliente atualizou o TLS de 1.0 para 1.2. Meu aplicativo está usando o .net framework 3.5 e é executado no servidor. Então eu o corrigi desta maneira:

  1. Corrija o programa

Antes de chamar HttpWebRequest.GetResponse (), adicione este comando:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolTypeExtensions.Tls11 | SecurityProtocolTypeExtensions.Tls12;

Extensões 2 DLLs adicionando 2 novas classes: System.Net e System.Security.Authentication

    namespace System.Net
    {
        using System.Security.Authentication;
        public static class SecurityProtocolTypeExtensions
        {
            public const SecurityProtocolType Tls12 = (SecurityProtocolType)SslProtocolsExtensions.Tls12;
            public const SecurityProtocolType Tls11 = (SecurityProtocolType)SslProtocolsExtensions.Tls11;
            public const SecurityProtocolType SystemDefault = (SecurityProtocolType)0;
        }
    } 

    namespace System.Security.Authentication
    {
        public static class SslProtocolsExtensions
        {
            public const SslProtocols Tls12 = (SslProtocols)0x00000C00;
            public const SslProtocols Tls11 = (SslProtocols)0x00000300;
        }
    } 
  1. Atualizar lote da Microsoft

Baixar lote:

  • Para o Windows 2008 R2: windows6.1-kb3154518-x64.msu
  • Para o Windows 2012 R2: windows8.1-kb3154520-x64.msu

Para lote de download e mais detalhes, você pode ver aqui:

https://support.microsoft.com/en-us/help/3154518/support-for-tls-system-default-versions-included-in-the-.net-framework-3.5.1-on-windows-7 -sp1-e-servidor-2008-r2-sp1

Hieu
fonte
1
é possível alterar o SecurityProtocol sem alterar o código fonte? como um machine.config ou app.config.
ahankendi
1
Uau. Esse é o prêmio vodu do ano ... coisa ... bem ali. Você balança os subúrbios!
granadaCoder
14

O mecanismo de alteração do registro funcionou para mim depois de uma luta. Na verdade, meu aplicativo estava rodando como 32 bits. Então eu tive que mudar o valor no caminho.

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft.NETFramework\v4.0.30319

O tipo de valor precisa ser DWORD e valor acima de 0. Melhor uso 1.As configurações do registro para obter o aplicativo .Net 4.0 usam o TLS 1.2, desde que o .Net 4.5 esteja instalado na máquina.

Joy George Kunjikkuru
fonte
Não é preciso. Para o .NET 4.5.2, isso precisa ser definido como 1 (ou superior); mas para o .NET 4.6, basta não ser definido como 0 (ou seja, pode ser desabilitado).
Jirka Hanika
Oh, eu não testei no .Net 4.6. Minhas descobertas estão lá no blogpost joymonscode.blogspot.com/2015/08/…
Joy George Kunjikkuru 15/15
A chave do registro mencionada deve ser "Wow6432Node". Você omitiu a parte "Nó" por algum motivo. Tentei editar sua resposta, mas minha alteração foi de apenas 4 letras, para que não me permitisse. : \
Jeffrey LeCours
Eu tive que devolver o IIS para que essa configuração fosse ativada como padrão.
Jeff Mitchell
10

Estou executando o .NET 4.5.2 e não fiquei satisfeito com nenhuma dessas respostas. Como estou conversando com um sistema que suporta TLS 1.2 e vendo como SSL3, TLS 1.0 e TLS 1.1 estão todos quebrados e inseguros para uso, não quero habilitar esses protocolos. No .NET 4.5.2, os protocolos SSL3 e TLS 1.0 são habilitados por padrão, o que posso ver no código inspecionando ServicePointManager.SecurityProtocol. No .NET 4.7, há o novoSystemDefaultmodo de protocolo que entrega explicitamente a seleção do protocolo ao sistema operacional, onde acredito que seria apropriado confiar no registro ou em outras configurações do sistema. No entanto, isso não parece ser suportado no .NET 4.5.2. No interesse de escrever código compatível com versões anteriores, isso continuará a tomar as decisões corretas, mesmo quando o TLS 1.2 for inevitavelmente quebrado no futuro, ou quando eu atualizar para o .NET 4.7+ e entregar mais responsabilidades pela seleção de um protocolo apropriado para o SO , Adotei o seguinte código:

SecurityProtocolType securityProtocols = ServicePointManager.SecurityProtocol;
if (securityProtocols.HasFlag(SecurityProtocolType.Ssl3) || securityProtocols.HasFlag(SecurityProtocolType.Tls) || securityProtocols.HasFlag(SecurityProtocolType.Tls11))
{
    securityProtocols &= ~(SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11);
    if (securityProtocols == 0)
    {
        securityProtocols |= SecurityProtocolType.Tls12;
    }
    ServicePointManager.SecurityProtocol = securityProtocols;
}

Esse código detectará quando um protocolo não seguro conhecido estiver ativado e, nesse caso, removeremos esses protocolos não seguros. Se nenhum outro protocolo explícito permanecer, forçaremos a ativação do TLS 1.2, como o único protocolo seguro conhecido suportado pelo .NET neste momento. Esse código é compatível com versões anteriores, pois levará em consideração novos tipos de protocolos que não conhece sobre a adição no futuro e também funcionará bem com o novoSystemDefaultno .NET 4.7, o que significa que não precisarei visitar novamente esse código no futuro. Eu recomendo fortemente a adoção de uma abordagem como essa, em vez de codificar qualquer estado de protocolo de segurança em particular incondicionalmente; caso contrário, você precisará recompilar e substituir seu cliente por uma nova versão para atualizar para um novo protocolo de segurança quando o TLS 1.2 está inevitavelmente quebrado ou é mais provável que você tenha que deixar os protocolos inseguros existentes ativados por anos no seu servidor, tornando a sua organização alvo de ataques.

Roger Sanders
fonte
1
Essa resposta parece ser a mais pensada, no entanto, a menos que esteja faltando alguma coisa, não tenho certeza de que será compatível com o futuro sempre que o TLS 1.2 for inevitavelmente interrompido. Pelo que estou vendo no meu aplicativo .NET 4.7.2, o SecurityProtocolType.SystemDefaultsinalizador é avaliado 0, portanto, verificar if (securityProtocols == 0)com o sinalizador inclusivo ou com sinal de bits do TLS 1.2 sempre incluirá o TLS 1.2, mesmo depois de "interrupções", certo? Não tiro nítido aqui. Estou realmente tentando encontrar o melhor caminho a seguir.
Griswald_911
I modificar seu código para incluir este e parece trabalhar e ser compatível: if (!Enum.IsDefined(typeof(SecurityProtocolType), 0) && securityProtocols == 0) { securityProtocols |= SecurityProtocolType.Tls12; }.
Griswald_911
@ Griswald_911, eu tenho código semelhante no meu aplicativo de console 4.7.2 e achei que esta linha securityProtocols |= SecurityProtocolType.Tls12;(sem bloco se) não mantém SystemDefault, os securityProtocols só têm TLS2 posteriormente. Então, quando o valor é SystemDefault, nenhum valor deve ser atualizado? Com relação ao encaminhamento compatível, você está assumindo que o sistema operacional cuidaria de habilitar um protocolo mais novo como o TLS 1.3?
219 Yang
@Yang - Correto. A linha securityProtocols |= SecurityProtocolType.Tls12;' will add TLS 1.2, but because the SecurityProtocolType` enum tem um [Flags]atributo, e o valor de enumeração SystemDefault é 0, o valor SystemDefault será removido, mesmo que tenha sido definido anteriormente. O resultado final é que você pode definir o valor SevicePointManager.SecurityProtocol 0 ou qualquer combinação dos outros valores de enumeração. Se você configurá-lo como SystemDefault, basicamente está optando por não especificar o protocolo e deixar o sistema operacional decidir.
Griswald_911
1
@Yang - O ponto é que, depois de definir o valor como SystemDefault, seu aplicativo deve usar o que o sistema operacional especificar - que é o TLS 1.2 nas versões mais recentes do Windows 10. A idéia é que, no futuro, quando o TLS 1.3 se tornar como padrão, você não precisa modificar seu aplicativo para herdar essa funcionalidade. Consulte a documentação aqui , onde SystemDefault "permite que o sistema operacional escolha o melhor protocolo a ser usado e bloqueie os protocolos que não são seguros".
Griswald_911
6

A Microsoft publicou recentemente as práticas recomendadas para isso. https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls

Resumo

Alvo .Net Framework 4.7, remova qualquer código que defina o SecurityProtocol, assim o sistema operacional garantirá que você use a solução mais segura.

NB: Você também precisará garantir que a versão mais recente do TLS seja suportada e ativada no seu sistema operacional.

OS                          TLS 1.2 support

Windows 10                  \_ Supported, and enabled by default.
Windows Server 2016         /   
Windows 8.1                 \_ Supported, and enabled by default.
Windows Server 2012 R2      /
Windows 8.0                 \_ Supported, and enabled by default.
Windows Server 2012         /
Windows 7 SP1               \_ Supported, but not enabled by default*.
Windows Server 2008 R2 SP1  /
Windows Server 2008         -  Support for TLS 1.2 and TLS 1.1 requires an update. See Update to add support for TLS 1.1 and TLS 1.2 in Windows Server 2008 SP2.
Windows Vista               -  Not supported.

* To enable TLS1.2 via the registry see https://docs.microsoft.com/en-us/windows-server/security/tls/tls-registry-settings#tls-12 

    Path: HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS1.2\Server

        Property: Enabled
        Type: REG_DWORD
        Value: 1

        Property: DisabledByDefault 
        Type: REG_DWORD
        Value: 0

    Path: HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS1.2\Client

        Property: Enabled
        Type: REG_DWORD
        Value: 1

        Property: DisabledByDefault 
        Type: REG_DWORD
        Value: 0

Para mais informações e estruturas mais antigas, consulte o link MS.

JohnLBevan
fonte
3
O problema é que o tls 1.1 e o tls 1.2 não funcionarão no Windows 7 e no Server 2008 se você seguir as diretrizes (mantendo o SecurityProtocolType.SystemDefault) porque eles não estão "ativados" (o que quer que isso signifique) nesses sistemas operacionais sem uma alteração no registro. Isso faz com que SystemDefault na prática seja quebrado por design. A Microsoft realmente estragou tudo.
Osexpert
Bom, obrigado @osexpert, boa captura. Alterei a resposta para incluir informações sobre os sistemas operacionais suportados, para que não haja surpresas para as pessoas que executam sistemas operacionais mais antigos, onde apenas a segmentação 4.7 não é suficiente.
9789 John DeBurnan
1
NB: Há também uma KB para habilitar os protocolos mais recentes em alguns sistemas operacionais: support.microsoft.com/en-my/help/3140245/…
JohnLBevan
1
Se as configurações do registro não são uma opção que eu acho que essa é a melhor solução para .NET 4.7+: if (System.Environment.OSVersion.Version < new Version(6, 2) /* Windows 8 */) ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; else ServicePointManager.SecurityProtocol = SecurityProtocolType.SystemDefault;
osexpert
5

Para completar, eis um script do Powershell que define as chaves de registro mencionadas acima:

new-itemproperty -path "HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319" -name "SchUseStrongCrypto" -Value 1 -PropertyType "DWord";
new-itemproperty -path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319" -name "SchUseStrongCrypto" -Value 1 -PropertyType "DWord"
qbik
fonte
2

Uma alternativa à codificação embutidaServicePointManager.SecurityProtocol ou à chave SchUseStrongCrypto explícita, conforme mencionado acima:
Você pode dizer ao .NET para usar as configurações SCHANNEL padrão com a chave SystemDefaultTlsVersions,
por exemplo:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319] "SystemDefaultTlsVersions"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319] "SystemDefaultTlsVersions"=dword:00000001
Alfred
fonte
2

A solução BEST para esse problema parece ser atualizar para pelo menos o .NET 4.6 ou posterior, que escolherá automaticamente protocolos fortes e cifras fortes.

Se você não pode atualizar para o .NET 4.6, o conselho de definir

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

E usando as configurações do registro:

HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft.NETFramework \ v4.0.30319 - SchUseStrongCrypto = DWORD de 1 HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ Microsoft.NETFramework \ v4.0.30319 - SchUseStrongCrypto = DWORD

Resultados no uso de algo diferente do TLS 1.0 e uma cifra forte.

Nos meus testes, apenas a configuração no Wow6432Node fez alguma diferença, mesmo que meu aplicativo de teste tenha sido criado para Qualquer CPU.

GWC
fonte
Esclarecimento: você só precisa definir o SevicePointManager.SecurityProtocol OU definir as configurações do registro. Não há necessidade de fazer as duas coisas. Para o meu aplicativo, optei apenas por definir o ServicePointManager.SecurityProtocol. Meu raciocínio é que a configuração do registro afeta toda a máquina e eu não queria que o aplicativo de outra pessoa fosse interrompido porque dependia do TLS 1.0.
GWC
1

De acordo com as práticas recomendadas de TLS (Transport Layer Security) com o .NET Framework : Para garantir que os aplicativos .NET Framework permaneçam seguros, a versão do TLS não deve ser codificada. Em vez disso, defina as chaves do registro: SystemDefaultTlsVersions e SchUseStrongCrypto :

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v2.0.50727]
"SystemDefaultTlsVersions"=dword:00000001
"SchUseStrongCrypto"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319]
"SystemDefaultTlsVersions"=dword:00000001
"SchUseStrongCrypto"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v2.0.50727]
"SystemDefaultTlsVersions"=dword:00000001
"SchUseStrongCrypto"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319]
"SystemDefaultTlsVersions"=dword:00000001
"SchUseStrongCrypto"=dword:00000001
Benjamin Freitag
fonte
0

Se você pode usar o .NET 4.7.1 ou mais recente, ele usará o TLS 1.2 como o protocolo mínimo com base nos recursos do sistema operacional. Por recomendação da Microsoft:

To ensure .NET Framework applications remain secure, the TLS version should not be hardcoded. .NET Framework applications should use the TLS version the operating system (OS) supports.
yanivhs
fonte
-2

Para chave: HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft.NETFramework \ v4.0.30319 Valor: SchUseStrongCrypto

Você deve definir o valor como 1.

kgw
fonte
5
Eu acho que você está sendo downvoted porque a sua a mesma resposta @Jira Mares oferecido, mas com menos detalhe
Stuart Siegler