如何解决“无法通过授权为SSL / TLS安全通道建立信任关系”


135

真的以为我已经解决了这个问题,但是以前只是变相了。

我有一个使用HTTPS在IIS 7中托管的WCF服务。当我在Internet Explorer中浏览到此站点时,它就像一个超级按钮一样工作,这是因为我已将证书添加到本地根证书颁发机构存储中。

我正在1台计算机上进行开发,因此客户端和服务器是同一台计算机。证书是直接从IIS 7管理单元自签名的。

我现在不断收到此错误...

无法使用权​​限建立SSL / TLS安全通道的信任关系。

...当从客户端控制台调用时。

我使用findprivatekey和手动为证书授予了权限和网络服务cacls.exe

我尝试使用SOAPUI连接到该服务,并且该方法有效,因此在我的客户端应用程序中这一定是一个问题,该应用程序的代码基于与HTTP一起使用的代码。

关于我为什么无法连接,我似乎还穷尽了所有其他可能性?



如果您可以控制证书的创建,请不要忘记“备用主题名称”。就像您可以将通配符放在“ * .full.domainname.com”中。参见digicert.com/subject-alternative-name.htm
granadaCoder

Answers:


198

解决方法是,您可以在客户端ServicePointManagerServerCertificateValidationCallback上添加一个处理程序:

System.Net.ServicePointManager.ServerCertificateValidationCallback +=
    (se, cert, chain, sslerror) =>
        {
            return true;
        };

但是请注意,这不是一个好习惯,因为它会完全忽略服务器证书,并告诉服务点管理器任何证书都可以,这会严重损害客户端安全性。您可以对此进行优化,并进行一些自定义检查(例如证书名称,哈希等)。至少您可以在使用测试证书的开发过程中规避问题。


9
我认为大多数公共设置都将使用购买的证书,但在开发人员期间,请在条件#if语句中使用上述代码。企业开发人员通常应设置内部CA服务器>> technet.microsoft.com/zh-cn/library/cc875810.aspx
Luke Puplett 2010年

2
帮助我弄清楚了如何使我的SSL WCF调用与Fiddler2一起进行调试。
Roger Willcocks

2
@karank考虑将其放在Global.asax的Application_Start方法中(请参阅stackoverflow.com/a/12507094/1175419)。我强烈建议使用#if DEBUG编译器指令或类似Luke注释中提到的内容。
Rich C

4
太棒了!您可以将lambda表达式用作System.Net.ServicePointManager.ServerCertificateValidationCallback + =(例如,se,cert,chain,sslerror)=> true;
Dhanuka777 '16

可以在这里找到一些额外的解释:blog.effectivemessaging.com/2015_09_01_archive.html
granadaCoder

40

当我遇到这个问题时,这是因为client.config具有以下端点:

 https://myserver/myservice.svc 

但是证书在期待

 https://myserver.mydomain.com/myservice.svc

更改端点以匹配服务器的FQDN解决了我的问题。我知道这不是此问题的唯一原因。


我只是再次遇到了这个问题,这一次必须使用错误的证书。在这两种情况下,似乎都与正确匹配名称有关。
Mike Cheel 2012年

3
我的自动生成的配置将<endpoint address =“ localhost / myservice.svc ”更改为<endpoint address =“ mymachine.mydoman.com/myservice.svc ”解决了此问题。
knightscharge

这绝对是我的问题,我花了两天时间找到您的答案。+1,如果可以的话,我会给你+1000。
AussieJoe

20

前两个使用lambda,第三个使用常规代码...希望对您有所帮助

            //Trust all certificates
            System.Net.ServicePointManager.ServerCertificateValidationCallback =
                ((sender, certificate, chain, sslPolicyErrors) => true);

            // trust sender
            System.Net.ServicePointManager.ServerCertificateValidationCallback
                = ((sender, cert, chain, errors) => cert.Subject.Contains("YourServerName"));

            // validate cert by calling a function
            ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateRemoteCertificate);

    // callback used to validate the certificate in an SSL conversation
    private static bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors policyErrors)
    {
        bool result = false;
        if (cert.Subject.ToUpper().Contains("YourServerName"))
        {
            result = true;
        }

        return result;
    }

1
//信任所有证书System.Net.ServicePointManager.ServerCertificateValidationCallback + =(se,cert,chain,sslerror)=> {返回true; }; //信任发件人System.Net.ServicePointManager.ServerCertificateValidationCallback + =(se,cert,chain,sslerror)=> {return cert.Subject.Contains(“ ca-1-9wfvrm1.ceridian.ca”); };
VoodooChild

1
任何破解者都可以伪造通过所有上述测试的证书。这是不安全的。
Bjartur Thorlacius

19

出现问题是因为您使用的是自签名密钥。客户端不信任此密钥,密钥本身也不提供验证链或证书吊销列表。

您有几种选择-您可以

  1. 关闭客户端上的证书验证(错误动作,中间人的攻击比比皆是)

  2. 使用makecert创建根CA并从中创建证书(可以,但是仍然没有CRL)

  3. 使用Windows证书服务器或其他PKI解决方案创建内部根CA,然后信任该根证书(管理起来有些麻烦)

  4. 从其中一个受信任的CA购买SSL证书(价格昂贵)


3
关于(4),StartSSL实际上会为您提供免费的1类证书,该证书可在所有主流浏览器中使用。它们对我的六个低带宽站点都非常有用。
moodboom

我认为此列表上的#2 ...此URL可能会有所帮助:blogs.technet.microsoft.com/jhoward/2005/02/02/… “如何使用MakeCert进行受信任的根证书颁发机构和SSL证书颁发”
granadaCoder

1
注:StartCom不再值得信任-而刚刚从Chrome中删除en.wikipedia.org/wiki/StartCom
Simon_Weaver

16

一线解决方案。在客户端调用服务器之前,将其添加到任何位置:

System.Net.ServicePointManager.ServerCertificateValidationCallback += delegate { return true; };

这仅应用于测试目的,因为客户端将跳过SSL / TLS安全检查。


2
一个出色的测试解决方法。我们正在使用一种服务,该服务的提供者通过一系列复杂的安全证书使安全变成了现实,直到我们能够获得其不稳定的证书和链接以使其正常工作之前,这种解决方法是唯一使我们能够继续开发的方法。
markaaronky

12

我遇到了同样的问题,并且可以通过两种解决方案解决该问题:首先,我将MMC管理单元“证书”用于“计算机帐户”,并将自签名证书拖到“受信任的根证书颁发机构”文件夹中。这意味着本地计算机(生成证书的计算机)现在将信任该证书。其次,我注意到该证书是为某个内部计算机名称生成的,但是正在使用另一个名称访问该Web服务。验证证书时,这会导致不匹配。我们为computer.operations.local生成了证书,但是使用https://computer.internaldomain.companydomain.com访问了Web服务。当我们将URL切换到用于生成证书的URL时,没有更多错误。

也许只是切换URL可能会起作用,但是通过使证书受信任,您还可以避免Internet Explorer中红屏,因为它告诉您它不信任证书。


11

如果您使用.net core,请尝试以下操作:

client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication =
        new X509ServiceCertificateAuthentication()
        {
            CertificateValidationMode = X509CertificateValidationMode.None,
            RevocationMode = System.Security.Cryptography.X509Certificates.X509RevocationMode.NoCheck
        };

1
谢谢,它有效。但这与.net核心无关。这是一个通用食谱:)
亚历山大

7

请执行以下步骤:

  1. 在IE中打开服务链接。

  2. 单击地址栏中提到的证书错误,然后单击查看证书。

  3. 支票签发给:姓名。

  4. 以发出的名称并将服务和客户端端点基本地址名称中的localhost替换为A完全限定的域名(FQDN)。

例如:https:// 本地主机:203 / SampleService.svc到https:// INL-126166-.groupinfra.com:203 / SampleService.svc


太好了,谢谢您的回答!解决了这些问题,无需更改任何代码。
Vipin Dubey

6

除上述答案外,如果客户端运行的TLS版本错误,例如服务器仅运行TLS 1.2,则可能会遇到此错误。

您可以使用以下方法修复它:

// tested in .NET 4.5:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

就我而言,被接受的答案并没有帮助我,但这是一个窍门
谢尔盖(Sergey)

这是纠正我的错误的唯一答案。
Tolga

5

我有同样的问题。我还在本地商店中添加了CA证书,但是我采用了错误的方式。

使用mmc控制台(开始->运行-> mmc),您应该将证书管理单元添加为服务帐户(选择IIS的服务帐户)或计算机帐户(它为计算机上的每个帐户添加)

这是我在说什么的图片 为服务帐户或计算机帐户添加管理单元

从现在开始,您可以添加CA的证书(受信任的根CA中间CA),并且一切正常


4

我对自签名证书有类似的问题。我可以使用与服务器的FQDN相同的证书名称来解决它。

理想情况下,应该在服务器端管理SSL部分。不需要客户端安装任何SSL证书。另外,有些文章提到有关从客户端代码绕过SSL的文章。但是我完全不同意。


3

我只是将证书拖到“受信任的根证书颁发机构”文件夹中,所以一切都很好。

哦。我首先从管理员命令提示符添加了以下内容:

netsh http add urlacl url=https://+:8732/Servicename user=NT-MYNDIGHET\INTERAKTIV

我不知道你需要的用户名(我的是挪威,你可以看到!) user=NT-AUTHORITY/INTERACTIVE

您可以通过发出以下命令来查看所有现有的urlacl: netsh http show urlacl


0

尝试通过WCF服务连接时发生这种情况。IP,例如https://111.11.111.1:port/MyService.svc,使用与名称(例如,mysite.com)绑定的证书。

切换到https://mysite.com:port/MyService.svc解决了。



0

刚刚解决了类似的问题。

我意识到我有一个在一个帐户下运行的应用程序池,该帐户仅具有对所使用证书的读取权限。

.NET应用程序可以正确检索证书,但是只有在调用GetRequestStream()时才会抛出该异常。

证书权限可以通过MMC控制台进行管理


0

如果您使用的是.net core,则在开发过程中可以使用编译器指令来绕过证书验证。这种方式只会验证证书的发布,而不是调试的证书:

#if (DEBUG)
        client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication =
                new X509ServiceCertificateAuthentication()
                {
                    CertificateValidationMode = X509CertificateValidationMode.None,
                    RevocationMode = System.Security.Cryptography.X509Certificates.X509RevocationMode.NoCheck
                };   #endif

-6

将此添加到您的客户端代码:

ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(
    delegate
    {
        return true;
    });

4
这个答案不是很好,因为它不能解释与代码相关的风险。
daveD 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.