【问题标题】:HttpClient - The message received was unexpected or badly formattedHttpClient - 收到的消息是意外的或格式错误
【发布时间】: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


【解决方案1】:

尝试使用 CreateFromPem 静态函数加载证书,该方法返回带有私钥的新证书。

var certificateCrt = File.ReadAllText("<Public Certificate>");
var privateKey = File.ReadAllText("<private key file>");
using var certificate = X509Certificate2.CreateFromPem(certificateCrt, privateKey);

如果这不起作用,请尝试使用 OpenSSL 创建 .pfx 证书:

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

当我需要在 Windows 操作系统上使用证书时,我遇到了这个问题,为了工作,我必须创建一个 .pfx 证书,但在 Mac 和 Linux 等其他操作系统上,没有 .pfx 证书也可以正常工作。

【讨论】:

  • 嗨,保罗,我试过了。不得不将我的项目升级到 .Net 5。但是它并没有解决我的问题。我尝试用wireshark拦截。当我尝试使用邮递员时,我可以看到整个 SSL 握手顺利进行。但是,我的应用程序会发送一个 TLS 警报:“警报(级别:致命,描述:协议版本)”,然后是 RST、ACK。同样在 Windows 事件查看器上,我得到:“创建 TLS 客户端凭据时发生致命错误。内部错误状态为 10013。”。我不确定问题是什么。你会知道这件事吗?我正在使用 Windows 10。
  • 您好,您是否尝试使用简单的 HttpClient 来发出请求? var bodyObject = new { }; using var httpClient = new HttpClient(handler); using var content = new StringContent(JsonSerializer.Serialize(bodyObject), Encoding.UTF8, "application/json"); var response = await httpClient.PostAsync("http://localhost:5000/api", content);
  • 是的。我剥离了一切。并尝试使用与您共享的内容非常相似的东西。仍然没有运气。无论是否添加证书,我都会收到相同的错误。 System.Net.Http.HttpRequestException:无法建立 SSL 连接,请参阅内部异常。 ---> System.Security.Authentication.AuthenticationException:身份验证失败,请参阅内部异常。 ---> System.ComponentModel.Win32Exception (0x80090326):收到的消息是意外的或格式错误。
  • 也在事件查看器上我得到这个:创建 TLS 客户端凭据时发生致命错误。内部错误状态为 10013。
  • 也尝试过这篇文章中提到的内容,但也可以使用:mariusbancila.ro/blog/2019/04/08/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-21
  • 2014-05-31
  • 1970-01-01
  • 2021-11-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多