A autenticação falhou porque a parte remota fechou o fluxo de transporte

87

Estou desenvolvendo um cliente TCP para conectar o servidor OpenSSL com a autenticação de certificado. Estou usando arquivos .crt e .key compartilhados pela equipe do servidor. Esses certificados são gerados por comandos OpenSSL.

Eu estou usando SslStreamobjeto para autenticar o cliente Tcp chamando SslStream.AuthenticateAsClientmétodo passando servidor IP, SslProtocols.Ssl3e X509CertificateCollection.

Eu estou recebendo o seguinte erro:

A autenticação falhou porque a parte remota fechou o fluxo de transporte

Odelu
fonte
2
Este parece ser um problema nos dias pós-POODLE: SslProtocols.Ssl3. Talvez você deva tentar SslProtocols.Tls. No .Net 4.5 e superior, você também pode usar Tls11ou Tls12. Consulte SslProtocols Enumeration . Você pode ter outros problemas.
jww
Obrigado. Meu problema é resolvido anexando o certificado do caminho físico do certificado e a senha em vez de pesquisar o nome do assunto do certificado no armazenamento de certificados do Windows.
Odelu
Agora consigo obter o resultado de todos os protocolos Ssl (SSL3, Tls1 e Tls2). Obrigado pela resposta
Odelu
@Odelu, como você resolveu o problema? Do lado do cliente ou do lado do servidor?

Respostas:

155

Aconselho a não restringir o SecurityProtocol ao TLS 1.1.

A solução recomendada é usar

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

Outra opção é adicionar a seguinte chave do Registro:

Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 
Value: SchUseStrongCrypto 

É importante notar que o .NET 4.6 usará o protocolo correto por padrão e não requer nenhuma das soluções.

GuiSim
fonte
6
uau, você resolveu meu problema - estava tentando todo tipo de coisa - e acabou vendo aqui a nota no framework. Apenas mudei para 4.6.1 (estava usando 4.5), esperando que o problema fosse que a estrutura pudesse estar usando o protocolo de segurança errado - e bingo, minhas conexões não estão sendo recusadas e estou recebendo meus dados!
Veverke
7
É importante dizer que System.Net.ServicePointManager.SecurityProtocol = ...deve ser executado antes de criar a solicitação.
Tonatio,
2
aquela atualização da versão do framework alvo para 4.6.1 salvou minha vida :-)
Awais
Minha estrutura está definida em 4.6.2. Talvez eu tenha que usar a solução TLS em vez
Luminous
Estou usando o 4.7.2 Framework e o site para o qual estou enviando a solicitação está usando o TLS 1.2, mas é como em 6 solicitações de 10, recebo esse erro. alguma ideia ?
Davit Mikuchadze
16

Se você quiser usar uma versão mais antiga do .net, crie seu próprio sinalizador e lance-o.

    //
    // Summary:
    //     Specifies the security protocols that are supported by the Schannel security
    //     package.
    [Flags]
    private enum MySecurityProtocolType
    {
        //
        // Summary:
        //     Specifies the Secure Socket Layer (SSL) 3.0 security protocol.
        Ssl3 = 48,
        //
        // Summary:
        //     Specifies the Transport Layer Security (TLS) 1.0 security protocol.
        Tls = 192,
        //
        // Summary:
        //     Specifies the Transport Layer Security (TLS) 1.1 security protocol.
        Tls11 = 768,
        //
        // Summary:
        //     Specifies the Transport Layer Security (TLS) 1.2 security protocol.
        Tls12 = 3072
    }
    public Session()
    {
        System.Net.ServicePointManager.SecurityProtocol = (SecurityProtocolType)(MySecurityProtocolType.Tls12 | MySecurityProtocolType.Tls11 | MySecurityProtocolType.Tls);
    }
Iguanaware
fonte
1
Você não precisa usar sua própria classe, você pode converter números inteiros diretamente para SecurityProtocolTypeServicePointManager.SecurityProtocol = (SecurityProtocolType) 48 | (SecurityProtocolType) 192 | (SecurityProtocolType) 768 | (SecurityProtocolType) 3072;
Yan F.,
13

Adicionar o código abaixo me ajudou a superar o problema.

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11;
Muruge
fonte
8
using (var client = new HttpClient(handler))
            {
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
                var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, apiEndPoint)).ConfigureAwait(false);
                await response.Content.ReadAsStringAsync().ConfigureAwait(false);
            }

Isso funcionou para mim

Sanket Sonavane
fonte
1
O bit crítico é a seguinte linha: ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; Essa resposta é ótima porque mostra onde essa linha deve se encaixar no caso de uso típico.
Nick Painter
5

Encontrei a mesma mensagem de erro ao usar o ChargifyNET.dll para me comunicar com a API Chargify. Adicionar chargify.ProtocolType = SecurityProtocolType.Tls12;à configuração resolveu o problema para mim.

Aqui está o snippet de código completo:

public ChargifyConnect GetChargifyConnect()
{
    var chargify = new ChargifyConnect();
    chargify.apiKey = ConfigurationManager.AppSettings["Chargify.apiKey"];
    chargify.Password = ConfigurationManager.AppSettings["Chargify.apiPassword"];
    chargify.URL = ConfigurationManager.AppSettings["Chargify.url"];

    // Without this an error will be thrown.
    chargify.ProtocolType = SecurityProtocolType.Tls12;

    return chargify;
}
Tod Birdsall
fonte
2

Para VB.NET, você pode colocar o seguinte antes de sua solicitação da web:

Const _Tls12 As SslProtocols = DirectCast(&HC00, SslProtocols)
Const Tls12 As SecurityProtocolType = DirectCast(_Tls12, SecurityProtocolType)
ServicePointManager.SecurityProtocol = Tls12

Isso resolveu meu problema de segurança no .NET 3.5.

user1477388
fonte
0

Isso aconteceu comigo quando um endpoint de solicitação da web foi alternado para outro servidor que aceitava apenas solicitações TLS1.2. Tentei tantas tentativas encontradas principalmente no Stackoverflow como

  1. Chaves de registro,
  2. Adicionado:
    System.Net.ServicePointManager.SecurityProtocol | = System.Net.SecurityProtocolType.Tls12; para Global.ASX OnStart,
  3. Adicionado em Web.config.
  4. Atualizado o framework .Net para 4.7.2 Ainda obtendo a mesma exceção.

A exceção recebida não fez justiça ao problema real que eu estava enfrentando e não encontrou ajuda da operadora do serviço.

Para resolver isso, tenho que adicionar um novo Cipher Suite TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 Eu usei a ferramenta IIS Crypto 2.0 daqui, conforme mostrado abaixo.

insira a descrição da imagem aqui

FunMatters
fonte