Https 从azure函数调用外部api时证书未验证

Https 从azure函数调用外部api时证书未验证,https,ssl-certificate,azure-functions,x509certificate,Https,Ssl Certificate,Azure Functions,X509certificate,我正在开发一个azure函数(应用程序服务计划),它调用和外部api。该api由证书保护 我已将证书上载到azure function SSL设置中。我在Azure功能设置中也有相关的指纹 我能够通过使用它的指纹拾取完全相同的证书 X509Store certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser); certStore.Open(OpenFlags.ReadOnly); var

我正在开发一个azure函数(应用程序服务计划),它调用和外部api。该api由证书保护

我已将证书上载到azure function SSL设置中。我在Azure功能设置中也有相关的指纹

我能够通过使用它的指纹拾取完全相同的证书

 X509Store certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
        certStore.Open(OpenFlags.ReadOnly);
        var cert1 = certStore.Certificates.Find(
                                    X509FindType.FindByThumbprint,                                       
                                    "xxxxxxxxxxxxxx",
                                    false)[0];
        log.LogInformation(cert1.Subject);
但是,当我使用HttpClient进行调用时,我会发现SSL错误

 var _clientHandler = new HttpClientHandler();
        _clientHandler.UseDefaultCredentials = false;
        _clientHandler.ClientCertificateOptions = ClientCertificateOption.Automatic;
        using (var client = new HttpClient(_clientHandler))
        {
         try
            {
                client.DefaultRequestHeaders.Accept.Clear();
                var resp = await client.GetAsync("https://xxxxxxxxxxxx");
我不想绕过验证,但为了检查发生了什么,我添加了此代码,链状态为“不可信”

我做错了什么

我做错了什么

没什么。您的客户端证书看起来可能已正确附加到请求。服务器证书验证回调表示执行请求的计算机不信任来自其发送请求的服务器的证书链

如果您将在Azure中看到的证书链(例如,
foreach(chain.chainements中的var elem){log.LogInformation(elem.certificate.Subject)}
)与从另一个源中看到的证书链进行比较,并且它们是相同的,那么您可以使回调更像

_clientHandler.ServerCertificateCustomValidationCallback =
(sender, cert, chain, sslPolicyErrors) =>
{
    if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateChainErrors)
    {
        X509ChainStatusFlags flags = chain.ChainStatus.Aggregate(
            X509ChainStatusFlags.NoError,
            (f, s) => f | s.Status);

        if (flags == X509ChainStatusFlags.UntrustedRoot)
        {
            X509Certificate2 presentedRoot =
                chain.ChainElements[chain.ChainElements.Length - 1].Certificate;

            return presentedRoot.RawData.SequenceEqual(s_pinnedRootBytes);
        }
    }

    return sslPolicyErrors == SslPolicyErrors.None;
};
只有在以下任一情况下,才会返回true:

  • 如果没有自定义回调,它会成功
  • 该链唯一的错误是它有一个不受信任的根,并且该链的根是逐字节的,等于您已经保存的根证书的副本。(硬编码、外部资源等。)

是的,你说的很有道理。您是如何定义“s_pinnedRootBytes”?s_pinnedRootBytes!!是我代码中“cert1”的“原始数据”吗?是指上传后我从azure获取的吗?@RaasMasood否,它是发布服务器证书的根权限的RawData值的(副本);您必须发现并添加到项目中的内容。
_clientHandler.ServerCertificateCustomValidationCallback =
(sender, cert, chain, sslPolicyErrors) =>
{
    if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateChainErrors)
    {
        X509ChainStatusFlags flags = chain.ChainStatus.Aggregate(
            X509ChainStatusFlags.NoError,
            (f, s) => f | s.Status);

        if (flags == X509ChainStatusFlags.UntrustedRoot)
        {
            X509Certificate2 presentedRoot =
                chain.ChainElements[chain.ChainElements.Length - 1].Certificate;

            return presentedRoot.RawData.SequenceEqual(s_pinnedRootBytes);
        }
    }

    return sslPolicyErrors == SslPolicyErrors.None;
};