[英]How to create and use a DNS-based self-signed certificate on different networks
I have the following code to create a self-signed certificate: 我有以下代码来创建自签名证书:
SubjectAlternativeNameBuilder subjectAlternativeNameBuilder = new SubjectAlternativeNameBuilder();
subjectAlternativeNameBuilder.AddDnsName("TestSRV01);
X500DistinguishedName x500DistinguishedName = new X500DistinguishedName($"CN=Self-Signed-Test");
using (RSA rsa = RSA.Create(2048))
{
var certificateRequest = new CertificateRequest(x500DistinguishedName, rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
certificateRequest.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.DataEncipherment | X509KeyUsageFlags.KeyEncipherment | X509KeyUsageFlags.DigitalSignature, false));
certificateRequest.CertificateExtensions.Add(new X509EnhancedKeyUsageExtension(new OidCollection { new Oid("2.5.29.32.0"), new Oid("1.3.6.1.5.5.7.3.1") }, false));
certificateRequest.CertificateExtensions.Add(subjectAlternativeNameBuilder.Build());
var certificate = certificateRequest.CreateSelfSigned(new DateTimeOffset(DateTime.UtcNow.AddDays(-1)), new DateTimeOffset(DateTime.UtcNow.AddDays(3650)));
return new X509Certificate2(certificate.Export( X509ContentType.Cert, pw), pw, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable);
}
I only add the DNS name of the server to avoid the binding to the current IP address (the test machine is moved around different networks). 我仅添加服务器的DNS名称, 以避免绑定到当前IP地址 (测试计算机在不同网络中移动)。
As it turned out, I need to use the IP address when I connect from the client (DNS resolving is unreliably on the test site). 事实证明,从客户端连接时,我需要使用IP地址(DNS解析在测试站点上是不可靠的)。
Unfortunately, the SSL connection fails with this message: 不幸的是,SSL连接失败并显示以下消息:
(Hostname 192.168.0.*** not verified: certificate: sha256/UuUOTTQTCb2wu************************ DN: CN=
(主机名192.168.0。***未通过验证:证书:sha256 / UuUOTTQTCb2wu **************************** DN:CN =
I can't bind the certificate to this address, but I also can't use the domain name as the connection parameter. 我不能将证书绑定到该地址,但是也不能使用域名作为连接参数。
Can I create a usable certificate around this problem? 我可以针对此问题创建可用的证书吗? Or should I modify the cert values whenever the computer boots up and add the current IP address to is
SubjectAlternativeName
list? 还是在计算机启动时将证书值添加到
SubjectAlternativeName
列表中,是否应该修改证书值?
Based on the comments it seems the best way to handle this case is to provide custom certificate verification in the clients, bearing in mind the caveats in Patrick Mevzek's comments. 根据评论,似乎最好的处理此情况的方法是考虑到Patrick Mevzek的评论中的警告,在客户端中提供自定义证书验证。
Custom certificate verification involves you writing your own code to verify certain aspects in the certificate. 自定义证书验证涉及您编写自己的代码以验证证书中的某些方面。 The
HttpClientHandler
class provides a ServerCertificateCustomValidationCallback
property that you can set with your own callback. HttpClientHandler
类提供了一个ServerCertificateCustomValidationCallback
属性,您可以使用自己的回调对其进行设置。
The certificate is evaluated first by .NET and then the results of this validation are passed to your callback as an SslPolicyErrors
enum along with the certificate. 证书首先由.NET评估,然后此验证的结果作为
SslPolicyErrors
枚举与证书一起传递到您的回调中。 You have several options for correcting the validation error(s). 您可以使用多个选项来更正验证错误。 See for example this answer for a hint.
例如,请参见此答案以获取提示。 Inside the callback you can examine the subject alt name in the hint and make sure it is "TestSRV01".
在回调内部,您可以检查提示中的主题替代名称,并确保它是“ TestSRV01”。
The GetNameInfo
method of X509Certificate2
can be used to retrieve only the first DNS name in the list of subject alternative names, so if the hostname you want to check is not the first one then you'll have to do battle with .NET to get the information you need. X509Certificate2
的GetNameInfo
方法可用于仅检索主题备用名称列表中的第一个DNS名称,因此,如果要检查的主机名不是第一个,则必须与.NET进行斗争才能获得您需要的信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.