在。net 3.1 linux docker容器中添加客户端证书可以工作,但在升级到。net 5时失败。我看到在。net 5中有一个突破性的变化,使用TLS 1.3和受限的密码套件,我如何在。net 5中使用类型化的HttpClient来覆盖它?使用类型化的HttpClient来指定更广泛的密码套件集。试图发送付款请求的站点仅支持tls 1.2,其ssllabs报告如下https://www.ssllabs.com/ssltest/analyze.html?d=mss.cpc.getswish.net
这是我的代码示例
services.AddHttpClient<ISwishpayService, SwishpayService>()
.ConfigurePrimaryHttpMessageHandler<SwishpayHandler>();
public class SwishpayHandler: HttpClientHandler
{
private readonly IConfiguration _config;
private readonly ILogger<SwishpayHandler> _logger;
public SwishpayHandler(IConfiguration config, ILogger<SwishpayHandler> logger)
{
_config = config;
_logger = logger;
SslProtocols = System.Security.Authentication.SslProtocols.Tls12 | System.Security.Authentication.SslProtocols.Tls13;
ClientCertificateOptions = ClientCertificateOption.Manual;
}
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken)
{
if (ClientCertificates == null || ClientCertificates.Count == 0)
{
_logger.LogInformation("Invoked SwishpayHandler");
using (X509Store store = new X509Store(StoreName.CertificateAuthority, StoreLocation.CurrentUser, OpenFlags.ReadWrite))
{
var certs = new X509Certificate2Collection();
certs.Import(Path.Combine("Certificates", _config.GetValue<string>("SwishApi:key:certificatefile")), GetCertificatePassword(), X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
foreach (X509Certificate2 cert in certs)
{
if (cert.HasPrivateKey)
{
ClientCertificates.Add(cert);
}
else
{
store.Add(cert);
}
}
store.Close();
}
}
return await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
}
private string GetCertificatePassword()
{
var cert_password = File.ReadAllText(_config.GetValue<string>("SWISHPAY_CERT_PWD").Trim()).Replace(Environment.NewLine, "");
return cert_password;
}
}
.net 5中的异常
System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
---> System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception.
---> Interop+OpenSsl+SslException: SSL Handshake failed with OpenSSL error - SSL_ERROR_SSL.
---> Interop+Crypto+OpenSslCryptographicException: error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
你的代码有几个与。net 5无关的问题。
问题# 1:
X509Store store = new X509Store(StoreName.CertificateAuthority, StoreLocation.CurrentUser, OpenFlags.ReadWrite)
为什么在StoreName.CertificateAuthority
中搜索客户端证书?存储名称必须为StoreName.My
问题# 2:
certs.Import(Path.Combine("Certificates", _config.GetValue<string>("SwishApi:key:certificatefile")), GetCertificatePassword(), X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
Sotre在CurrentUser
上下文中打开,但是由于某些未知的原因您指定了X509KeyStorageFlags.MachineKeySet
。为什么?必须是X509KeyStorageFlags.UserKeySet
。
尝试以下操作,
using (X509Store store = new X509Store(StoreName.CertificateAuthority, StoreLocation.CurrentUser, OpenFlags.ReadWrite))
{
var certs = new X509Certificate2Collection();
certs.Import(settings.Value.ClientCertPath, settings.Value.ClientCertSecret, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
foreach (X509Certificate2 cert in certs)
{
if (cert.HasPrivateKey)
{
ClientCertificates.Add(cert);
logger.LogInformation("CertTest: " + cert.Thumbprint);
}
else
{
store.Add(cert);
logger.LogInformation("CertTest store: " + cert.Thumbprint);
}
}
store.Close();
}