使用RestSharp在请求中添加证书

24

我正在尝试与服务器进行通信。该服务器向我发送了一个证书和私钥,以便成功执行我的请求。

为了测试服务器,我使用Postman。所以我在Postman中填写证书设置,然后我的请求运行良好。

Postman settings for certificates

现在我想在C#中做同样的事情。

为此,我使用RestSharp创建请求。

这是我的代码:

 var client = new RestClient(url);

 byte[] certBuffer = UtilsService.GetBytesFromPEM(myCertificate, Models.Enum.PemStringType.Certificate);
 byte[] keyBuffer = UtilsService.GetBytesFromPEM(encryptedPrivateKey, Models.Enum.PemStringType.RsaPrivateKey);

 X509Certificate2 certificate = new X509Certificate2(certBuffer, secret);
 client.ClientCertificates = new X509CertificateCollection() { certificate };
 var request = new RestRequest(Method.POST);
 request.AddHeader("Cache-Control", "no-cache");
 request.AddHeader("Accept", "application/json");
 request.AddHeader("Content-Type", "application/json");
 request.AddParameter("myStuff", ParameterType.RequestBody);
 IRestResponse response = client.Execute(request);

请求无法正常工作。我认为问题源于我在RestSharp中加载证书的方式。

我正在寻找如何在RestSharp中正确设置证书的信息。

我正在使用RestSharp,但也可以使用其他适用于C#的工具。


1
不知道您是否已经在使用Postman,它具有一个内置的功能,可以将请求导出为大多数流行的编程语言之一。其中包括C#,它使用RestSharp库。只需在屏幕右上方附近点击代码按钮,然后选择c#即可。如果您已经知道这个功能,那么请原谅我冗长的解释! - user7159857
1
是的,我已经用这种方式生成了代码。但它没有考虑到证书的问题... - dpfauwadel
明白了。很抱歉,我希望我能帮助你,但是我不知道该怎么做。 - user7159857
3个回答

42

好的,我找到了解决方案。

首先,我必须停止使用.crt和.key证书文件,而是需要得到一个.pfx后缀的证书。这可以通过openssl命令(openssl文档)来完成。

openssl pkcs12 -export -out certificate.pfx -inkey privateKey.key -in certificate.crt -certfile CACert.crt

创建证书后,只需像这样将其添加到请求中:

var client = new RestClient(url);

ServicePointManager.Expect100Continue = true;
ServicePointManager.DefaultConnectionLimit = 9999;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;

var certFile = Path.Combine(certificateFolder, "certificate.pfx");
X509Certificate2 certificate = new X509Certificate2(certFile, onboard.authentication.secret);
client.ClientCertificates = new X509CertificateCollection() { certificate };
client.Proxy = new WebProxy();
var restrequest = new RestRequest(Method.POST);
restrequest.AddHeader("Cache-Control", "no-cache");
restrequest.AddHeader("Accept", "application/json");
restrequest.AddHeader("Content-Type", "application/json");
restrequest.AddParameter("myStuff", ParameterType.RequestBody);
IRestResponse response = client.Execute(restrequest);

1
+1 给问答都点赞。我花了一个小时寻找一个简单的解决方案。最终,找到了一些可行的方法。谢谢! - Gaspa79
3
在我添加了这行代码 System.Net.ServicePointManager.ServerCertificateValidationCallback += (s, cert, chain, sslPolicyErrors) => true; 之后,这个程序对我有效。我希望这对其他人也有用。 - Arindam Nayak
我能够使用.p12文件而不是.pfx文件。
var certFile = Path.Combine("C:\\Projects\\Certs\\", "CERTFILE_SHA2.p12");
- Cale Sweeney
@Arindam-Nayak,你可以使用这行代码跳过证书验证 :) - Akbar Asghari
需要使用代理来使用证书吗?那个代理的作用是什么?指的是这个:client.Proxy = new WebProxy(); - Cale Sweeney
显示剩余4条评论

1

使用 RestSharp v107 版本对我来说没有用。我在这里发布了解决方案:https://dev59.com/4nkPtIcB2Jgan1znkV3G#73559615

总结一下 - RestClient 构造函数使用 Options 证书配置 HttpClientHandler,但在 RestClient 构造完成后将证书设置到 Options 中,却未能添加到底层的 HttpClientHandler 对象中。


1

这不是显式的,但我认为就是这样。

 var options = new RestClientOptions(url)
        {
            ClientCertificates = new System.Security.Cryptography.X509Certificates.X509CertificateCollection() { certificate.Certificate }
           
        };
        var client = new RestClient(options);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接