首页 > 解决方案 > C# RestSharp 客户端证书获取异常“无法建立 SSL 连接”

问题描述

我在放置此代码的 C# .Net Core 3.1 和 .Net 标准库中进行编程。

我没有收到带有未安装在服务器/计算机上的客户端证书的 RestSharp 的 http 请求,我将无法访问稍后将运行的服务器/计算机。

我的代码:

                // Create a RestSharp RestClient objhect with the base URL
                var client = new RestClient(_baseAPIUrl);

                // Create a request object with the path to the payment requests
                var request = new RestRequest("swish-cpcapi/api/v1/paymentrequests");

                // Create up a client certificate collection and import the certificate to it
                X509Certificate2Collection clientCertificates = new X509Certificate2Collection();
                clientCertificates.Import(_certDataBytes, _certificatePassword, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);

                // Add client certificate collection to the RestClient
                client.ClientCertificates = clientCertificates;

                //X509Certificate2 certificates = new X509Certificate2(_certDataBytes, _certificatePassword);

                //client.ClientCertificates = new X509CertificateCollection() { certificates };

                // Add payment request data
                request.AddJsonBody(requestData);

                var response = client.Post(request);
                var content = response.Content;

我已经完成了我在互联网上可以找到的任何事情,并且我使用了带有自己生成证书的服务测试环境,并在生产环境中生成了我自己的证书,结果相同..

我已经测试了设置 TLS 1.1 或 TLS 1.2 来测试,他们在自己的 curl 示例中指定了 TLS 1.1。

有人知道吗?

更新 2020-01-08 - 我从服务技术支持人员那里得到信息,他们只看到我发送了一个证书,但是当我尝试调试和检查 X509Certificate2Collection 时,我发现了 3 个证书。但他们说他们只看到一个?

标签: c#.net.net-corerestsharpclient-certificates

解决方案


恕我直言,如果您尝试访问的服务受到 SSL 证书的保护,并且需要公钥/私钥,那么如果没有证书,您将无法访问它。如果那是要保护服务的意图,我认为您可能只检查服务健康检查或最大检查服务是否可访问(没有客户端证书)

但就像 HTTPS 一样,如果您可以从浏览器访问服务 URL,则可以尝试从浏览器下载证书,例如访问其元数据或简单的 GET 或其他东西。在 chrome 中,您可能会在 URL 之前看到一个锁定符号(安全图标)。单击它,您可能会下载公共证书。您可以将其安装在您的机器上并尝试一下。

如果该服务具有 pub 证书并且访问不需要客户端证书,则上述选项可能有效。我希望您正在安装 CERT 并通过您的代码从有权访问证书的帐户访问它。假设您将证书安装在 LocalSystem 下,那么您可能需要从代码/解决方案进行管理员访问才能访问该证书路径。或者将证书安装在 current_user 路径下。

作为第一步,我将检查是否能够从浏览器访问该服务。

这就是我从你的问题中了解到的。同样,如果您可以解释该服务是否是基于公钥/私钥的受保护服务,则您需要拥有访问/证书才能使用该服务。

更新: 通过创建演示 api 和演示客户端来使用客户端证书,我已经尝试了几个选项。根据我从您的查询中了解到的情况,我假设以下可能是您尝试的一些选项。

// --- using the cert path if you have the path (instead of the byte[])
var myCert = new X509Certificate2("<path to the client cert.cer/.pfx>", "secure-password", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
X509CertificateCollection clientCerts = new X509CertificateCollection();
clientCerts.Add(myCert);

或者

var certStore = new X509Store(StoreName.Root, StoreLocation.LocalMachine); //replace with appropriate values based on your cert configuration
certStore.Open(OpenFlags.ReadOnly);

//option 1 (ideally a client must have the cert thumbprint instead of a password 
var cert = certStore.Certificates.Find(X509FindType.FindByThumbprint, "<cert Thumbprint>", false);

//option 2 (explore other options based on X509NameTypes
var cert = certStore.Certificates.OfType<X509Certificate2>()
                    .FirstOrDefault(cert => cert.GetNameInfo(X509NameType.DnsName, false) == "mycompany.dns.name.given in the cert");

client.ClientCertificates = new X509CertificateCollection(cert);

推荐阅读