ChatGPT解决这个技术问题 Extra ChatGPT

如何解决“无法为具有权限的 SSL/TLS 安全通道建立信任关系”

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

我正在一台机器上开发,所以客户端和服务器是同一台机器。证书是直接从 IIS 7 管理单元中自签名的。

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

无法为具有权限的 SSL/TLS 安全通道建立信任关系。

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

我使用 findprivatekeycacls.exe 手动为自己授予证书的权限和网络服务。

我尝试使用 SOAPUI 连接到服务,并且可以正常工作,因此它一定是我的客户端应用程序中的一个问题,它是基于过去使用 http 的代码。

我还能在哪里看我似乎已经用尽了所有可能性,为什么我无法连接?

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

s
sharptooth

作为一种解决方法,您可以在客户端向 ServicePointManagerServerCertificateValidationCallback 添加一个处理程序:

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

但请注意,这不是一个好的做法,因为它完全忽略了服务器证书并告诉服务点管理器任何证书都可以,这可能会严重危及客户端安全。您可以对此进行改进并进行一些自定义检查(针对证书名称、哈希等)。至少可以在使用测试证书时规避开发过程中出现的问题。


我认为大多数公共设置将使用购买的证书,但在开发期间在条件 #if 语句中使用上述代码。企业开发人员通常应该设置一个内部 CA 服务器>> technet.microsoft.com/en-us/library/cc875810.aspx
帮助我弄清楚如何让我的 SSL WCF 调用与 Fiddler2 一起工作以进行调试。
@karank 考虑将它放在 Global.asax 的 Application_Start 方法中(参见 stackoverflow.com/a/12507094/1175419)。我强烈建议使用 #if DEBUG 编译器指令或卢克评论中提到的类似指令。
惊人的!您可以将 lambda 表达式用作 System.Net.ServicePointManager.ServerCertificateValidationCallback += (se, cert, chain, sslerror) => true;
可以在这里找到一些额外的解释:blog.effectivemessaging.com/2015_09_01_archive.html
M
Mike Cheel

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

 https://myserver/myservice.svc 

但证书是期待的

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

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


我又遇到了这个问题,这次它必须使用错误的证书。似乎在这两种情况下,它都与正确匹配名称有关。
我的自动生成配置已将 <endpoint address="localhost/myservice.svc" 更改为 <endpoint address="mymachine.mydoman.com/myservice.svc" 解决了这个问题。
这绝对是我的问题,我花了两天时间才找到你的答案。 +1,如果可以的话,我会给你+1000。
b
blowdart

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

你有几个选择 - 你可以

关闭客户端上的证书验证(糟糕的举动,中间人攻击比比皆是)使用 makecert 创建根 CA 并从中创建证书(好的移动,但仍然没有 CRL)使用 Windows 证书服务器创建内部根 CA或其他 PKI 解决方案然后信任该根证书(管理起来有点麻烦)从一个受信任的 CA 购买 SSL 证书(昂贵)


关于 (4),StartSSL 实际上会给您一个免费的 1 类证书,该证书适用于所有主要浏览器。它们对我的六个低带宽站点非常有用。
我认为此列表中的 #2...此 url 可能会有所帮助:blogs.technet.microsoft.com/jhoward/2005/02/02/…“如何使用 MakeCert 进行受信任的根证书颁发机构和 SSL 证书颁发”
注意:StartCom 不再值得信赖 - 刚刚从 Chrome en.wikipedia.org/wiki/StartCom 中删除
R
Romano Zumbé

前两个使用 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;
    }

//信任所有证书 System.Net.ServicePointManager.ServerCertificateValidationCallback += (se, cert, chain, sslerror) => { return true; }; // 信任发送者 System.Net.ServicePointManager.ServerCertificateValidationCallback += (se, cert, chain, sslerror) => { return cert.Subject.Contains("ca-l-9wfvrm1.ceridian.ca"); };
任何破解者都可以伪造通过上述所有测试的证书。这是不安全的。
G
Gaspa79

单线解决方案。在客户端调用服务器之前添加这个:

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

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


测试的绝妙解决方法。我们正在使用一项服务,其提供者通过复杂的安全证书链使安全成为活生生的地狱,直到我们能够让他们的不稳定证书和链接正常工作,这种解决方法是唯一允许我们继续开发的方法。
J
Jeroen-bart Engelen

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

也许只是切换 URL 就可以了,但是通过使证书受信任,您还可以避免 Internet Explorer 中的红屏,它告诉您它不信任证书。


这最初对我不起作用。我必须对上述步骤进行一项修改:拖动证书时,确保按住 Ctrl 键以便复制证书,而不是从 Personal/Certificates 移动到 Trusted Root Certification Authorities/Certificates。
G
Grzegorz J

如果你使用 .net core 试试这个:

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

谢谢,它有效。但它与.net core 无关。这是一个通用的食谱:)
R
Rahul Rai

请执行以下步骤:

在 IE 中打开服务链接。单击地址栏中提及的证书错误,然后单击查看证书。支票发给:姓名。获取发布的名称并将服务和客户端端点基地址名称中提及的 localhost 替换为完全限定的域名 (FQDN)。

例如: https://localhost:203/SampleService.svc 到 https://INL-126166-.groupinfra.com:203/SampleService.svc


太好了,感谢您的回答!无需更改任何代码即可解决问题。
c
crusy

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

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

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

在我的情况下,接受的答案对我没有帮助,但是这个做了一个把戏
这是在我的案例中纠正错误的唯一答案。
这也是帮助我的技巧,尽管使用.Net 4.7.2
d
dar0x

我有同样的问题。我还在本地商店中添加了 CA 证书,但我做错了。

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

https://i.stack.imgur.com/hemGc.png

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


U
Umesh Bhavsar

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

理想情况下,SSL 部分应在服务器端进行管理。客户端不需要为 SSL 安装任何证书。此外,还提到了一些关于从客户端代码绕过 SSL 的帖子。但我完全不同意这一点。


j
j0k

我只是将证书拖到“受信任的根证书颁发机构”文件夹中,瞧一切正常。

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

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

我不确定您需要的用户名称(如您所见,我的是挪威语!):user=NT-AUTHORITY/INTERACTIVE

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


p
phifi

我只是想在@NMrt 已经指出的答案中添加一些内容:

如果您的客户端运行错误的 TLS 版本,您可能会遇到此错误,例如,如果服务器仅运行 TLS 1.2。

对于 Framework 4.7.2,如果您没有像这样在 web.config 中显式配置目标框架

<system.web>
  <compilation targetFramework="4.7" />
  <httpRuntime targetFramework="4.7" />
</system.web>

您的系统默认安全协议将被忽略,而可能会使用“较低”的安全协议。在我的情况下是 Ssl3/Tls 而不是 Tls13。

您也可以通过设置 SecurityProtocol(保持其他协议正常工作)在代码中解决此问题: System.Net.ServicePointManager.SecurityProtocol |= System.Net.SecurityProtocolType.Tls12 | System.Net.SecurityProtocolType.Tls11; System.Net.ServicePointManager.SecurityProtocol &= ~System.Net.SecurityProtocolType.Ssl3;

甚至通过添加注册表项来启用或禁用强加密 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319] "SchUseStrongCrypto"=dword:00000001

这篇博文为我指明了正确的方向,并比我更好地解释了背景:

https://www.ryadel.com/en/asp-net-client-server-cannot-comunicate-because-they-possess-common-algorithm-how-to-fix-c-sharp/


l
lko

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

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


s
sonia

这发生在尝试仅使用主机名(例如 https://host/MyService.svc)连接到 WCF 服务,同时使用与名称绑定的证书(例如 host.mysite.com)。

切换到 https://host.mysite.com/MyService.svc 并解决了它。


A
Alberto

刚刚修复了一个类似的问题。

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

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

可以通过 MMC console 管理证书权限


P
Panayiotis Hiripis

如果您使用的是 .net 核心,那么在开发期间您可以使用编译器指令绕过证书验证。这种方式只会验证证书的发布而不是调试:

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

m
metasapien

为了帮助进行故障排除,您可以临时添加它以记录有关导致验证失败的证书的其他信息。我将它记录到 NLog 的 txt 日志中,但您可以根据需要创建 EventLog:

System.Net.ServicePointManager.ServerCertificateValidationCallback += (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) =>
{
    StringBuilder sb = new StringBuilder();
    sb.AppendLine($"  Certificate Subject: {certificate.Subject}");
    sb.AppendLine($"  Certificate Issuer: {certificate.Issuer}");
    sb.AppendLine($"  Certificate CertHash: {certificate.GetCertHashString()}");
    sb.AppendLine($"  Certificate EffectiveDate: {certificate.GetEffectiveDateString()}");
    sb.AppendLine($"  Certificate ExpirationDate: {certificate.GetExpirationDateString()}");
    sb.AppendLine($"  sslPolicyErrors: {sslPolicyErrors.ToString()}");
    sb.AppendLine($"  ChainPolicy:");
    sb.AppendLine($"     Chain revocation flag: {chain.ChainPolicy.RevocationFlag}");
    sb.AppendLine($"     Chain revocation mode: {chain.ChainPolicy.RevocationMode}");
    sb.AppendLine($"     Chain verification flag: {chain.ChainPolicy.VerificationFlags}");
    sb.AppendLine($"     Chain verification time: {chain.ChainPolicy.VerificationTime}");
    sb.AppendLine($"     Chain status length: {chain.ChainStatus.Length}");
    sb.AppendLine($"     Chain application policy count: {chain.ChainPolicy.ApplicationPolicy.Count}");
    sb.AppendLine($"     Chain certificate policy count: {chain.ChainPolicy.CertificatePolicy.Count}");

    sb.AppendLine($"  ChainStatus:");
    foreach (var cs in chain.ChainStatus)
    {
        sb.AppendLine($"     Chain certificate policy count: Status: {cs.Status}, StatusInformation: {cs.StatusInformation}");
    }

    NLog.Common.InternalLogger.Error($"ServerCertificateValidationCallback: {sb}\n");

    return true;
};

B
Bokambo

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

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

这个答案不是很好,因为它没有解释与代码相关的风险。

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅