绕过证书验证

bal*_*dre 5 c# ssl

我无法绕过生产服务器中的证书验证,因为ServicePointManager.ServerCertificateValidationCallback从未调用过:

ServicePointManager.ServerCertificateValidationCallback = ValidateRemoteCertificate;

...

private bool ValidateRemoteCertificate(
    object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors policyErrors)
{
    LogActionToTable(EntrySeverity.Information, 
        $"ValidateRemoteCertificate() Certificate name: {cert.Subject}");
    return true;
}
Run Code Online (Sandbox Code Playgroud)

当从 Web 应用程序中的方法调用时,该行永远不会执行,奇怪的是它是从单元测试 (NUnit) 中正确调用的。

我确实在对远程 API 进行任何其他调用之前添加了此调用。

我究竟做错了什么?

如果我这样做,它甚至不起作用:

ServicePointManager
  .ServerCertificateValidationCallback += 
    (sender, cert, chain, sslPolicyErrors) => true;
Run Code Online (Sandbox Code Playgroud)

这一定非常简单,但我已经研究了好几天了,但我无法让它正常工作。


无论我是使用手动构建 XML 的 RestSharp 调用,还是通过wsdl.exe工具生成的代理进行调用,我总是会从调用中获取以下内容:

请求被中止:无法创建 SSL/TLS 安全通道。

并启用跟踪到日志文件中,我得到:

System.Net Information: 0 : [7912] SecureChannel#14469269 - Certificate is of type X509Certificate2 and contains the private key. System.Net Information: 0 : [7912] AcquireCredentialsHandle(package = Microsoft Unified Security Protocol Provider, intent = Outbound, scc = System.Net.SecureCredential) System.Net Information: 0 : [7912] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = (null), targetName = onni.unicom.fi, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation) System.Net Information: 0 : [7912] InitializeSecurityContext(In-Buffer length=0, Out-Buffer length=170, returned code=ContinueNeeded). System.Net Information: 0 : [7912] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = 14899210:2119fd0, targetName = onni.unicom.fi, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation) System.Net Information: 0 : [7912] InitializeSecurityContext(In-Buffers count=2, Out-Buffer length=0, returned code=CredentialsNeeded). System.Net Information: 0 : [7912] SecureChannel#14469269 - We have user-provided certificates. The server has specified 1 issuer(s). Looking for certificates that match any of the issuers. System.Net Information: 0 : [7912] SecureChannel#14469269 - Left with 0 client certificates to choose from. System.Net Information: 0 : [7912] Using the cached credential handle. System.Net Information: 0 : [7912] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = 14899210:2119fd0, targetName = onni.unicom.fi, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation) System.Net Information: 0 : [7912] InitializeSecurityContext(In-Buffers count=2, Out-Buffer length=173, returned code=ContinueNeeded). System.Net Information: 0 : [7912] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = 14899210:2119fd0, targetName = onni.unicom.fi, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation) System.Net Information: 0 : [7912] InitializeSecurityContext(In-Buffers count=2, Out-Buffer length=0, returned code=CertUnknown). System.Net Error: 0 : [7912] Exception in HttpWebRequest#25731266:: - The request was aborted: Could not create SSL/TLS secure channel.. System.Net Error: 0 : [7912] Exception in HttpWebRequest#25731266::EndGetRequestStream - The request was aborted: Could not create SSL/TLS secure channel..

最重要的:

System.Net 信息:0:[7912] InitializeSecurityContext(输入缓冲区计数=2,输出缓冲区长度=0,返回代码= CertUnknown)。

为什么调用不绕过这个ServicePointManager.ServerCertificateValidationCallback


没有代理的代码:

    private CardBalanceInfo ApiGetCardBalance(string cardNumber)
    {
        LogActionToTable(EntrySeverity.Information, $"ApiGetCardBalance('{cardNumber}')");

        var soapEnvelope =
                "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
                "  <soap:Header/>" +
                "  <soap:Body>" +
                "    <csi:getBalance xmlns:csi=\"urn:si.tm.webservice.uniassociation.unicom.com\">" +
                "      <csi:balanceId>" +
               $"        <entityName>{cardNumber}</entityName>" +
                "      </csi:balanceId>" +
                "    </csi:getBalance>" +
                "  </soap:Body>" +
                "</soap:Envelope>";

        const string soapUrl = "treasurymanagement/si";
        const string soapAction = "http://www.unicom.fi/uAASTreasuryManagementSI/getBalance";
        var response = MakeApiCall(soapUrl, soapAction, soapEnvelope);

        return response.ToBalanceInfo();
    }
Run Code Online (Sandbox Code Playgroud)

带代理的代码:

    private CardBalanceInfo ApiGetCardBalanceFromProxy(string cardNumber)
    {
        LogActionToTable(EntrySeverity.Information, $"ApiGetCardBalanceFromProxy('{cardNumber}')");

        using (var service = new uAASTreasuryManagementSIService())
        {
            service.Timeout = 10000; // 10 sec
            service.Url = _settings.BaseUrl.TrimEnd('/') + "/treasurymanagement/si";
            service.ClientCertificates.Add(_clientCertificate);

            var card = new getBalance()
            {
                balanceId = new EntityId
                {
                    entityName = cardNumber
                }
            };

            var balanceResponse = service.getBalance(card); // get API response

            LogActionToTable(EntrySeverity.Information, $"ApiGetCardBalanceFromProxy success.");

            return new CardBalanceInfo()
            {
                AvailableBalance = balanceResponse.balance.availableBalanceValue,
                Balance = balanceResponse.balance.balanceValue,
                BalanceId = balanceResponse.balance.balanceId.ToString()
            };
        }
    }
Run Code Online (Sandbox Code Playgroud)

Ste*_*ell 0

我不认为证书验证是您的问题。

在对证书进行自定义验证时使用ServerCertificateValidationCallback 。这在开发或质量保证环境中最常见,其中证书的主机名与您正在调用的服务的 URL 不匹配。

您会知道何时遇到此问题,因为您将收到包含以下错误详细信息的 SecurityNeogtiationException:

其他信息:无法与权限“{HOSTNAME}”建立 SSL/TLS 安全通道的信任关系

以下是我关闭本地计算机上的 ServerCertificateValidationCallback 时的情况。

在此输入图像描述

我建议你将注意力转移到

请求被中止:无法创建 SSL/TLS 安全通道。

因为这似乎是完全不同的问题。幸运的是我没有遇到过:-)这里的答案将是一个很好的起点: 请求被中止:无法创建 SSL/TLS 安全通道

华泰