2017-11-11 15 views
0

Mein Problem hier ist speziell in .net Standard 2.0, da der gleiche Code auf .NET-Framework funktioniert aus Gründen, die ich nicht ganz sicher bin.selbst signierte Zertifikate in .net Standard 2.0

Das Problem ist, dass ich HTTP-Anfragen an einen Server machen möchte, der selbstsignierte Zertifikate verwendet. Nun ist der Weg daran vorbei, in .net Framework (speziell 4.6.1) zu verwenden:

ServicePointManager.ServerCertificateValidationCallback = CustomValidation; 

public static bool CustomValidation 
      (object sender, 
      X509Certificate certificate, 
      X509Chain chain, 
      SslPolicyErrors policyErrors) 
     { 
      return true; 
     } 

Und das löst das Problem. Dies scheint jedoch im .net-Standard zu kompilieren, aber derselbe Fehler (WinHttpException - Ein Sicherheitsfehler ist aufgetreten) System.AggregateException aufgetreten HResult = 0x80131500 Meldung = Ein oder mehrere Fehler sind aufgetreten. (Beim Senden der Anforderung ist ein Fehler aufgetreten.) Quelle = StackTrace: bei System.Threading.Tasks.Task`1.GetResultCore (Boolean waitCompletionNotification) bei matrix_tester.Program.Main (String [] args) in C: \ Benutzer \ Nick \ Quelle \ Repos \ Matrix-Tester \ Program.cs: Zeile 11

Innerer Ausnahme 1: HttpRequestException: ein Fehler trat bei dem Senden der Anforderung auf.

Interne Ausnahme 2: WinHttpException: Ein Sicherheitsfehler aufgetreten

Ich bin mit meinem Latein Ende. Wird ServicePointManager nicht im .net-Standard verwendet?

+0

Haben Sie eine Lösung gefunden, um das selbstsignierte Zertifikat mit dem .NET-Standard 2.0 zu umgehen? –

Antwort

0

ServicePointManager sollte in 2.0 verfügbar sein.

Haftungsausschluss. Ich weiß nicht, warum dein Code nicht funktioniert. Ich habe einen Hack, den ich immer benutze, wenn ich Zertifikate automatisch akzeptieren muss. Es funktioniert in 2.0. Beachten Sie jedoch, dass dieses Skript ALLE selbstsignierten Zertifikate akzeptiert, was eine Sicherheitsverletzung darstellt. Verwenden Sie nach eigenem Ermessen. Es ist eine Singleton-Klasse. Rufen Sie es einfach am Anfang Ihres Programms wie folgt an:

Certificates.Instance.GetCertificatesAutomatically(); 

Und es sollte in Ihrem gesamten Programm funktionieren. Hoffe es hilft dir weiter zu kommen.

using System; 
using System.Collections.Generic; 
using System.Security; 
using System.Net; 
using System.Security.Cryptography.X509Certificates; 
using System.Security.Cryptography; 
using System.Net.Security; 

namespace test 
{ 
    public sealed class Certificates 
    { 
     private static Certificates instance = null; 
     private static readonly object padlock = new object(); 

     Certificates() 
     { 
     } 

     public static Certificates Instance 
     { 
      get 
      { 
       lock (padlock) 
       { 
        if (instance == null) 
        { 
         instance = new Certificates(); 
        } 
        return instance; 
       } 
      } 
     } 
     public void GetCertificatesAutomatically() 
     { 
      ServicePointManager.ServerCertificateValidationCallback += 
       new RemoteCertificateValidationCallback((sender, certificate, chain, policyErrors) 
        => { return true; }); 
     } 

     private static bool RemoteCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) 
     { 
      //Return true if the server certificate is ok 
      if (sslPolicyErrors == SslPolicyErrors.None) 
       return true; 

      bool acceptCertificate = true; 
      string msg = "The server could not be validated for the following reason(s):\r\n"; 

      //The server did not present a certificate 
      if ((sslPolicyErrors & 
       SslPolicyErrors.RemoteCertificateNotAvailable) == SslPolicyErrors.RemoteCertificateNotAvailable) 
      { 
       msg = msg + "\r\n -The server did not present a certificate.\r\n"; 
       acceptCertificate = false; 
      } 
      else 
      { 
       //The certificate does not match the server name 
       if ((sslPolicyErrors & 
        SslPolicyErrors.RemoteCertificateNameMismatch) == SslPolicyErrors.RemoteCertificateNameMismatch) 
       { 
        msg = msg + "\r\n -The certificate name does not match the authenticated name.\r\n"; 
        acceptCertificate = false; 
       } 

       //There is some other problem with the certificate 
       if ((sslPolicyErrors & 
        SslPolicyErrors.RemoteCertificateChainErrors) == SslPolicyErrors.RemoteCertificateChainErrors) 
       { 
        foreach (X509ChainStatus item in chain.ChainStatus) 
        { 
         if (item.Status != X509ChainStatusFlags.RevocationStatusUnknown && 
          item.Status != X509ChainStatusFlags.OfflineRevocation) 
          break; 

         if (item.Status != X509ChainStatusFlags.NoError) 
         { 
          msg = msg + "\r\n -" + item.StatusInformation; 
          acceptCertificate = false; 
         } 
        } 
       } 
      } 

      //If Validation failed, present message box 
      if (acceptCertificate == false) 
      { 
       msg = msg + "\r\nDo you wish to override the security check?"; 
       //   if (MessageBox.Show(msg, "Security Alert: Server could not be validated", 
       //      MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1) == DialogResult.Yes) 
       acceptCertificate = true; 
      } 

      return acceptCertificate; 
     } 

    } 
} 
+0

Dies scheint nicht zu funktionieren (obwohl ich nicht sehen kann, warum), wie es scheint ServicePointManager.ServerCertificateValidationCallback + = neue RemoteCertificateValidationCallback ((Absender, Zertifikat, Kette, policyErrors) => {return true;}); scheint nicht für mich zu arbeiten ... –

+0

Ich setze einen Breakpoint in den Delegaten, der schlagen sollte und es nicht ist? –

Verwandte Themen