【问题标题】:self signed certificates in .net standard 2.0.net 标准 2.0 中的自签名证书
【发布时间】:2018-04-24 16:56:04
【问题描述】:

我的问题特别是在 .net 标准 2.0 中,因为我不完全确定的原因似乎相同的代码在 .net 框架上工作。

问题是我想向使用自签名证书的服务器发出 http 请求。现在在 .net 框架(特别是 4.6.1)中解决这个问题的方法是使用:

ServicePointManager.ServerCertificateValidationCallback = CustomValidation;

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

这解决了问题。但是,在 .net 标准中执行此操作似乎可以编译但同样的错误(WinHttpException - 发生安全错误) System.AggregateException 发生 H结果=0x80131500 Message=发生了一个或多个错误。 (发送请求时出错。) 来源= 堆栈跟踪: 在 System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification) 在 C:\Users\Nick\source\repos\matrix-tester\Program.cs:line 11 中的 matrix_tester.Program.Main(String[] args) 处

内部异常 1: HttpRequestException: 发送请求时出错。

内部异常 2: WinHttpException: 发生安全错误

我的智慧到此为止。 .net 标准中不使用 ServicePointManager 吗?

【问题讨论】:

  • 您是否找到任何解决方案来绕过使用 .NET 标准 2.0 的自签名证书?

标签: c# post https get


【解决方案1】:

ServicePointManager 应该在 2.0 中可用。

免责声明。我不知道为什么你的代码不起作用。当我需要自动接受证书时,我总是使用一个 hack。它适用于 2.0。但请记住,此脚本接受所有自签名证书,这违反了安全性。自行决定使用。这是一个单例类。只需在程序开始时这样调用它:

Certificates.Instance.GetCertificatesAutomatically();

它应该在您的整个程序中都有效。希望对你有所帮助。

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;
        }

    }
}

【讨论】:

  • 这似乎不起作用(虽然我不明白为什么),因为它似乎 ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback((sender, certificate, chain, policyErrors) => { return true ; });似乎对我不起作用...
  • 我在委托中设置了一个断点,它应该命中,但没有?
猜你喜欢
  • 2012-05-10
  • 2018-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-02
  • 1970-01-01
  • 1970-01-01
  • 2022-07-07
相关资源
最近更新 更多