HttpClient 拒绝发送自签名客户端证书
HttpClient refusing to send self-signed client certificate
我正在尝试使用 HttpClient
和以下代码 发送 自签名 客户端证书 :
var handler = new HttpClientHandler();
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.ClientCertificates.Add(GetClientCertificate()); //Loads cert from a .pfx file
var client = new HttpClient(handler);
PerformRequest(client);
我看过很多与此相关的 SO 帖子,但是 none 解决了我的问题。
注意事项:
- 我已通过 Wireshark 验证服务器正在请求客户端证书,但
HttpClient
没有发送客户端证书。
- 当我使用 Postman 执行请求时,发送了完全相同的证书(使用相同的 .pfx 文件)
- 我已尝试通过
handler.SslProtocols
将 TLS 版本强制为 1.0、1.1、1.2 -- none 有效
- 从
GetClientCertificate()
返回的X509Certificate2
有私钥
- 这是在 .NET Framework 4.7.2 上的 -- 我无法更改它
我已经对此问题进行了 3 天的故障排除,甚至通读了参考资料,试图找出为什么我的证书未包含在内,但我找不到原因。
我怀疑在 HttpClient
实现的某个深处,我的证书被拒绝了,因为它是自签名的。
如何强制它发送我的证书? (服务器维护一个白名单,所以我不在乎它是否认为我的证书无效)。
或者,至少,我怎样才能从中获得任何类型的调试信息?有什么办法可以找到拒绝证书的原因吗?
更新:
启用跟踪后,我发现 .NET 正在正确选择我的证书:
System.Net Information: 0 : [23960] SecureChannel#64538993 - Selected certificate: <omitted>
System.Net Information: 0 : [23960] SecureChannel#64538993 - Left with 1 client certificates to choose from.
System.Net Information: 0 : [23960] SecureChannel#64538993 - Trying to find a matching certificate in the certificate store.
System.Net Information: 0 : [23960] SecureChannel#64538993 - Locating the private key for the certificate: <omitted>
System.Net Information: 0 : [23960] SecureChannel#64538993 - Certificate is of type X509Certificate2 and contains the private key.
System.Net Information: 0 : [23960] SecureChannel#64538993::.AcquireClientCredentials, new SecureCredential() (flags=(ValidateManual, NoDefaultCred, SendAuxRecord), m_ProtocolFlags=(Tls12Client), m_EncryptionPolicy=RequireEncryption)
System.Net Information: 0 : [23960] AcquireCredentialsHandle(package = Microsoft Unified Security Protocol Provider, intent = Outbound, scc = System.Net.SecureCredential)
System.Net Information: 0 : [23960] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = 21c5cd98:21cd2108, targetName = <omitted>, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation)
System.Net Information: 0 : [23960] InitializeSecurityContext(In-Buffers count=2, Out-Buffer length=100, returned code=ContinueNeeded).
... etc
然而,它仍然没有被发送。非常感谢任何有关在哪里查看的更多想法。
引导我找到了解决方案。
X509Certificate2.PrivateKey
抛出 NotSupportedException
因为我使用 ECD 作为签名算法。我切换到 RSA,现在它可以正确发送证书。
奇怪的是,跟踪显示ECD证书没有问题,并且能够成功识别私钥。我不知道为什么会这样——这对我来说听起来像是一个错误。尽管如此,RSA 仍适用于我的用例,我厌倦了调试它。
我正在尝试使用 HttpClient
和以下代码 发送 自签名 客户端证书 :
var handler = new HttpClientHandler();
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.ClientCertificates.Add(GetClientCertificate()); //Loads cert from a .pfx file
var client = new HttpClient(handler);
PerformRequest(client);
我看过很多与此相关的 SO 帖子,但是 none 解决了我的问题。
注意事项:
- 我已通过 Wireshark 验证服务器正在请求客户端证书,但
HttpClient
没有发送客户端证书。
- 当我使用 Postman 执行请求时,发送了完全相同的证书(使用相同的 .pfx 文件)
- 我已尝试通过
handler.SslProtocols
将 TLS 版本强制为 1.0、1.1、1.2 -- none 有效 - 从
GetClientCertificate()
返回的X509Certificate2
有私钥 - 这是在 .NET Framework 4.7.2 上的 -- 我无法更改它
我已经对此问题进行了 3 天的故障排除,甚至通读了参考资料,试图找出为什么我的证书未包含在内,但我找不到原因。
我怀疑在 HttpClient
实现的某个深处,我的证书被拒绝了,因为它是自签名的。
如何强制它发送我的证书? (服务器维护一个白名单,所以我不在乎它是否认为我的证书无效)。 或者,至少,我怎样才能从中获得任何类型的调试信息?有什么办法可以找到拒绝证书的原因吗?
更新:
启用跟踪后,我发现 .NET 正在正确选择我的证书:
System.Net Information: 0 : [23960] SecureChannel#64538993 - Selected certificate: <omitted>
System.Net Information: 0 : [23960] SecureChannel#64538993 - Left with 1 client certificates to choose from.
System.Net Information: 0 : [23960] SecureChannel#64538993 - Trying to find a matching certificate in the certificate store.
System.Net Information: 0 : [23960] SecureChannel#64538993 - Locating the private key for the certificate: <omitted>
System.Net Information: 0 : [23960] SecureChannel#64538993 - Certificate is of type X509Certificate2 and contains the private key.
System.Net Information: 0 : [23960] SecureChannel#64538993::.AcquireClientCredentials, new SecureCredential() (flags=(ValidateManual, NoDefaultCred, SendAuxRecord), m_ProtocolFlags=(Tls12Client), m_EncryptionPolicy=RequireEncryption)
System.Net Information: 0 : [23960] AcquireCredentialsHandle(package = Microsoft Unified Security Protocol Provider, intent = Outbound, scc = System.Net.SecureCredential)
System.Net Information: 0 : [23960] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = 21c5cd98:21cd2108, targetName = <omitted>, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation)
System.Net Information: 0 : [23960] InitializeSecurityContext(In-Buffers count=2, Out-Buffer length=100, returned code=ContinueNeeded).
... etc
然而,它仍然没有被发送。非常感谢任何有关在哪里查看的更多想法。
X509Certificate2.PrivateKey
抛出 NotSupportedException
因为我使用 ECD 作为签名算法。我切换到 RSA,现在它可以正确发送证书。
奇怪的是,跟踪显示ECD证书没有问题,并且能够成功识别私钥。我不知道为什么会这样——这对我来说听起来像是一个错误。尽管如此,RSA 仍适用于我的用例,我厌倦了调试它。