C# 如何在Linux的.NET内核中将客户端证书附加到HttpClient?

C# 如何在Linux的.NET内核中将客户端证书附加到HttpClient?,c#,linux,ssl,.net-core,C#,Linux,Ssl,.net Core,我正在.NETCore中创建一个控制台应用程序,用于调用内部WebAPI。内部API要求将客户端证书附加到请求。控制台应用程序将在Linux上安装和运行,特别是RHEL7。控制台应用程序目前正在使用.NET core 3.1,尽管我在.NET core 2.2上也遇到了同样的问题。我正在Windows10上开发控制台应用程序 我遇到的问题是,当应用程序从RHEL运行时,请求失败,API服务器返回403.7禁止响应,这意味着没有包含客户端证书。我可以运行应用程序并从Windows 10成功连接到w

我正在.NETCore中创建一个控制台应用程序,用于调用内部WebAPI。内部API要求将客户端证书附加到请求。控制台应用程序将在Linux上安装和运行,特别是RHEL7。控制台应用程序目前正在使用.NET core 3.1,尽管我在.NET core 2.2上也遇到了同样的问题。我正在Windows10上开发控制台应用程序

我遇到的问题是,当应用程序从RHEL运行时,请求失败,API服务器返回403.7禁止响应,这意味着没有包含客户端证书。我可以运行应用程序并从Windows 10成功连接到web API。我还可以在Windows10上运行该应用程序并从Ubuntu WSL成功连接

我有一个带有自定义
HttpClientHandler
HttpClientHandler
实现,如下所示:

public class MyClient : HttpClient {
        public MyClient() : base(getRequestHandler()) {         
        }
        private static HttpClientHandler getRequestHandler() {
            try {
                var requestHandler = new HttpClientHandler();
                X509Certificate2 certificate = null;

                /* Get Certificate */
                var pathToPfx = string.Empty;
                if (ConfigurationManager.AppSettings["certificateFileName"] != null) {
                    pathToPfx = ConfigurationManager.AppSettings["certificateFileName"].ToString();
                }
                var pfxPassword = string.Empty;
                if(ConfigurationManager.AppSettings["certificatePassword"] != null) {
                    pfxPassword = ConfigurationManager.AppSettings["certificatePassword"].ToString();
                }

                // load certificate
                log.Debug($"Loading certificate from {pathToPfx}");
                if (!string.IsNullOrEmpty(pfxPassword)) {
                    certificate = new X509Certificate2(pathToPfx, pfxPassword);
                } else {
                    certificate = new X509Certificate2(pathToPfx);
                }

                // add certificate to request
                if (certificate != null) {
                    requestHandler.ClientCertificates.Add(certificate);
                }

                return requestHandler;
            } catch (Exception ex) {
                log.Error(ex, ex.Message);
                throw;
            }
        }
    }
我的目的是能够将指定的证书附加到请求,但不必依赖证书存储,因为我不确定Linux上的支持级别。看起来我应该能够独立附加指定的证书文件。我的理解是,客户端证书需要私钥才能工作,在以.pfx文件和密码形式出现的Windows上,但在Linux上,它可以是单个b64编码的证书文件,只要它同时具有公钥和私钥

在Windows上,我有一个.pfx证书文件,可以用来连接API。如果我将应用程序指向该文件,并包含密码,则一切都会正常工作。但是我无法在Linux中使用.pfx文件,所以我使用openSSL(在WSL上)从.pfx文件中分别解析出证书和私钥。然后,我将这两部分合并到一个与Linux兼容的证书文件“mycert.cer”中:

通过引用该文件,我可以在WSL上运行该应用程序,它将成功连接到API。我还可以对cert文件运行openSSL,它看起来是有效的

在RHEL系统上,我可以针对API url运行curl,传入新证书,如下所示:
curl-v--cert mycert.cer'https://my.internal.server/url“
它会成功地回来。 但是当web请求是从控制台应用程序发出的,在RHEL中运行时,我得到上面提到的403禁止响应

在Windows或Linux上运行时,如何将客户端证书附加到HttpClient?我是否遗漏了证书在Linux上的工作方式,在Linux上,当从RHEL运行私钥时,即使它在文件中,它实际上也不会发送私钥?我想知道我是在试图解决RHEL系统中的一些环境问题,还是我只是在代码中做了一些错误的事情


谢谢你的帮助,

我也有同样的问题。你找到解决方案了吗?@Sai我最终坚持使用.pfx和相应的密码;我从来就不能得到一个普通的PEM,包括工作的私钥。我想我的部分问题是我不能从我的Windows机器上获取一个pfx文件并在linux上使用它。我聘请了系统管理员,他们从我们的AD服务器生成了一个证书,并在linux上建立了一个带有密码的p12,我将证书路径和密码传递给我的服务。我想复制一个独立的示例,并提交给github进行进一步的故障排除。是的,我认为最好使用.pfx。此外,我在linux容器中使用.pfx和http客户机使其正常工作。如果你还需要帮助,请告诉我。
-----BEGIN PRIVATE KEY-----
...key data...
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
...cert data...
-----END CERTIFICATE-----