无法为SSL / TLS安全通道建立信任关系-Windows Server 2012 R2

问题描述 投票:0回答:1

我知道关于StackOverflow和其他资源上此错误的很多信息,但是它在我的开发机上运行正常,现在在客户环境Windows Server 2012上运行。这是我的代码。

public sealed class Certificates
{
    private static bool subscribed = false;

    private static Certificates instance = null;

    private static readonly object padlock = new object();

    private Certificates() { }

    public static Certificates Instance
    {
        get
        {
            lock (padlock)
            {
                if (instance == null)
                    instance = new Certificates();
                return instance;
            }
        }
    }

    public void GetCertificatesAutomatically()
    {
        if (!subscribed)
        {
            ServicePointManager.ServerCertificateValidationCallback +=
                RemoteCertificateValidationCallback;
            //new RemoteCertificateValidationCallback((sender, certificate, chain, policyErrors) => { return true; });
            ServicePointManager.Expect100Continue = true;
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 |
                                                   SecurityProtocolType.Tls |
                                                   SecurityProtocolType.Tls11 |
                                                   SecurityProtocolType.Tls12;
            ServicePointManager.MaxServicePointIdleTime = 0;
            subscribed = 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;
        StringBuilder msg = new StringBuilder("The server could not be validate for the following reason():");

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

            // There is som other problem with certificate
            if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) == SslPolicyErrors.RemoteCertificateChainErrors)
            {
                foreach (X509ChainStatus item in chain.ChainStatus)
                {
                    if (item.Status != X509ChainStatusFlags.RevocationStatusUnknown &&
                        item.Status != X509ChainStatusFlags.OfflineRevocation)
                    {
                        SLICLog.Error($"    - {item.StatusInformation}.");
                        break;
                    }
                    if (item.Status != X509ChainStatusFlags.NoError)
                    {
                        msg.AppendLine($"    - {item.StatusInformation}.");
                        acceptCertificate = false;
                    }
                }
            }
        }

        // if validation failed, write log
        if (!acceptCertificate)
        {
            acceptCertificate = true;
        }

        return acceptCertificate;
    }
}

然后我使用了下一个代码

 Host = new Uri(credential.Domain);

 if (Host.Scheme.Contains("https"))
     Certificates.Instance.GetCertificatesAutomatically();
using (HttpWebResponse httpWebResponse = httpRequest.GetResponse() as HttpWebResponse)
            using (var response = httpWebResponse.GetResponseStream())
            using (var sr = new StreamReader(response))
            {
                token = JsonConvert.DeserializeObject<SessionInternal>(sr.ReadToEnd());
                if (token != null)
                {
                    Authorized = true;
                    token.Exprired = DateTime.Now.AddSeconds(Convert.ToDouble(token.expires_in));
                }
            }

问题是在环境计算机上,ServerCertificateValidationCallback被忽略了(我从为调试而添加的日志中知道这一点。

[在一个网站上,我读到Microsoft不允许它忽略服务器计算机上的自签名证书,但不确定。相同的代码在Windows10上可用,在Windows Server 2012上不可用,API服务器的设置也相同,我的意思是主机URL和凭据相同。.NET Framework 4.7.2

UPDATED:

我不知道为什么,但是另一台带有自签名证书的服务器可以工作,我的意思是我在环境服务器上运行代码以与另一台API服务器(这是另一种API)一起工作,并调用了ServerCertificateValidationCallback委托。我试图通过Wireshark研究网络,这是客户端/服务器之间连接不良的一部分enter image description here这是与另一台服务器的正常连接enter image description here我很困惑,但是相同的代码,只有不同的API服务器IP和不同的行为

c# windows-services windows-server-2012-r2
1个回答
0
投票

我遇到相同的问题-Windows 10也可以正常工作,Server 2012 R2不能。我已经尝试了从.Net 4.6到4.7.2到4.8的所有内容,并且在Win 10中可以正常运行,但在Win Server 2012 R2中则无法运行]

© www.soinside.com 2019 - 2024. All rights reserved.