【发布时间】:2021-05-25 12:08:29
【问题描述】:
我正在尝试连接到需要配置两种方式 SSL 的 API。我有我在邮递员中配置的证书和私钥,如下图所示。
这在 Postman 中运行良好,但是当我尝试使用 HttpClient 在 C# 中实现它时 SSL 失败。我得到的错误是“收到的消息意外或格式错误。”。我认为这与错误的配置有关。
我已经参考了这篇 StackOverflow 帖子来实现我的代码:Associate a private key with the X509Certificate2 class in .net
以下是我尝试过的:
byte[] publicCertificateBytes = File.ReadAllBytes("<Public Certificate>");
var publicCertificate = new X509Certificate2(publicCertificateBytes);
byte[] privateKey = Convert.FromBase64String(File.ReadAllText("<private key file>").Replace("-----BEGIN PRIVATE KEY-----", "").Replace("-----END PRIVATE KEY-----", ""));
using (var rsa = RSA.Create())
{
rsa.ImportPkcs8PrivateKey(privateKey, out _);
publicCertificate = publicCertificate.CopyWithPrivateKey(rsa);
publicCertificate = new X509Certificate2(publicCertificate.Export(X509ContentType.Pkcs12));
}
var httpService = new GenericUtilityManager().ResolveUtility<IHttpService>();
var handler = new HttpClientHandler();
handler.SslProtocols = SslProtocols.Tls12;
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.ClientCertificates.Add(publicCertificate);
handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
httpService.InitializeHttpClientHandler(handler);
请帮忙。
【问题讨论】:
-
我建议将邮递员发出的请求与从代码调用时发出的请求进行比较。使用 fiddler 或一些拦截工具会有所帮助。
-
你为什么使用
handler.SslProtocols = SslProtocols.Tls12;?这说don't use TLS1.3 even if the server requires it。默认情况下,.NET Core(至少从 4.6.2 开始)将使用最好的可用加密版本。至于错误,这意味着客户端和服务器无法就加密设置达成一致。 限制handler.SslProtocols = SslProtocols.Tls12;的设置可能会导致这种情况。 -
@shahkalpesh 我尝试用wireshark拦截。当我尝试使用邮递员时,我可以看到整个 SSL 握手顺利进行。但是,我的应用程序会发送一个 TLS 警报:“警报(级别:致命,描述:协议版本)”,然后是 RST、ACK。同样在 Windows 事件查看器上,我得到:“创建 TLS 客户端凭据时发生致命错误。内部错误状态为 10013。”。我不确定问题是什么。我的项目在 .Net 5.0 上。
-
@PanagiotisKanavos TLS1.2 对于这个项目是强制性的。因此规范。
-
您使用的是哪个操作系统版本?仍在主流支持中的 Windows 版本(Windows 10、Windows Server 2016 及更高版本)直接支持 TLS1.2。所有以前的版本都需要打补丁。这已记录在案,并且在 2016 年主要服务开始需要 TLS1.2 时提出了很多类似的问题
标签: c# ssl dotnet-httpclient