L'authentification a échoué car la partie distante a fermé le flux de transport

87

Je développe un client TCP pour connecter le serveur OpenSSL avec l'authentification par certificat. J'utilise des fichiers .crt et .key partagés par l'équipe du serveur. Ces certificats sont générés par des commandes OpenSSL.

J'utilise un SslStreamobjet pour authentifier le client Tcp en appelant la SslStream.AuthenticateAsClientméthode en passant le serveur IP, SslProtocols.Ssl3et X509CertificateCollection.

Je reçois l'erreur suivante:

L'authentification a échoué car la partie distante a fermé le flux de transport

Odelu
la source
2
Cela ressemble à un problème dans les jours post-Caniche: SslProtocols.Ssl3. Tu devrais peut-être essayer SslProtocols.Tls. Dans .Net 4.5 et supérieur, vous pouvez également utiliser Tls11ou Tls12. Consultez l' énumération SslProtocols . Vous pouvez avoir d'autres problèmes.
jww
Merci. Mon problème est résolu en attachant le certificat à partir du chemin physique du certificat et du mot de passe au lieu de rechercher le nom du sujet du certificat dans le magasin de certificats Windows.
Odelu
Maintenant, je suis en mesure d'obtenir le résultat de tous les SslProtocols (SSL3, Tls1 et Tls2) .Merci pour la réponse
Odelu
@Odelu, comment avez-vous résolu le problème? Côté client ou côté serveur?

Réponses:

155

Je déconseille de restreindre le SecurityProtocol à TLS 1.1.

La solution recommandée est d'utiliser

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

Une autre option consiste à ajouter la clé de registre suivante:

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

Il est à noter que .NET 4.6 utilisera le protocole correct par défaut et ne nécessite aucune solution.

GuiSim
la source
6
wow, vous venez de régler mon problème - j'essayais toutes sortes de choses - et vous avez fini par voir la note sur le cadre. Je viens de le passer à 4.6.1 (utilisait 4.5), en espérant que le problème serait que le framework utilise peut-être le mauvais protocole de sécurité - et au bingo, mes connexions ne sont pas refusées et je reçois mes données!
Veverke
7
Il est important de dire que System.Net.ServicePointManager.SecurityProtocol = ...doit être exécuté avant de créer la demande.
Tonatio
2
cette mise à jour de la version du framework cible vers 4.6.1 m'a sauvé la vie :-)
Awais
Mon cadre est fixé à 4.6.2. Peut-être que je devrai utiliser la solution TLS à la place
Lumineux
J'utilise 4.7.2 Framework également le site auquel j'envoie la demande utilise TLS 1.2 mais c'est comme à 6 demandes de 10 j'obtiens cette erreur. des idées ?
Davit Mikuchadze le
16

Si vous souhaitez utiliser une ancienne version de .net, créez votre propre indicateur et lancez-le.

    //
    // 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
la source
1
Vous n'avez pas besoin d'utiliser votre propre classe, vous pouvez directement convertir des entiers en SecurityProtocolTypeServicePointManager.SecurityProtocol = (SecurityProtocolType) 48 | (SecurityProtocolType) 192 | (SecurityProtocolType) 768 | (SecurityProtocolType) 3072;
Yan F.
13

L'ajout du code ci-dessous m'a aidé à résoudre le problème.

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11;
muruge
la source
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);
            }

Cela a fonctionné pour moi

Sanket Sonavane
la source
1
Le bit critique est la ligne suivante: ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; Cette réponse est excellente car elle montre où cette ligne doit s'inscrire dans le cas d'utilisation typique.
Nick Painter
5

J'ai rencontré le même message d'erreur lors de l'utilisation de ChargifyNET.dll pour communiquer avec l'API Chargify. Ajouterchargify.ProtocolType = SecurityProtocolType.Tls12; de la configuration a résolu le problème pour moi.

Voici l'extrait de code complet:

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
la source
2

Pour VB.NET, vous pouvez placer les éléments suivants avant votre requête Web:

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

Cela a résolu mon problème de sécurité sur .NET 3.5.

user1477388
la source
0

Cela m'est arrivé lorsqu'un point de terminaison de requête Web a été basculé vers un autre serveur qui n'acceptait que les requêtes TLS1.2. J'ai essayé tant de tentatives trouvées principalement sur Stackoverflow comme

  1. Clés de registre,
  2. Ajouté:
    System.Net.ServicePointManager.SecurityProtocol | = System.Net.SecurityProtocolType.Tls12; à Global.ASX OnStart,
  3. Ajouté dans Web.config.
  4. Mise à jour du framework .Net à 4.7.2 Toujours la même exception.

L'exception reçue n'a pas rendu justice au problème réel auquel j'étais confronté et n'a trouvé aucune aide de la part de l'opérateur de service.

Pour résoudre ce problème, je dois ajouter une nouvelle suite de chiffrement TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 J'ai utilisé l'outil IIS Crypto 2.0 à partir d' ici, comme indiqué ci-dessous.

entrez la description de l'image ici

FunMatters
la source