如何在不同网络上创建和使用基于 DNS 的自签名证书
How to create and use a DNS-based self-signed certificate on different networks
我有以下代码来创建自签名证书:
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);
}
我只添加了服务器的DNS名称避免绑定到当前IP地址(测试机在不同的网络中移动)
事实证明,我从客户端连接时需要使用 IP 地址(测试站点上的 DNS 解析不可靠)。
不幸的是,SSL 连接失败并显示此消息:
(Hostname 192.168.0.*** not verified:
certificate: sha256/UuUOTTQTCb2wu************************
DN: CN=
我无法将证书绑定到这个地址,而且我也无法使用域名作为连接参数。
我可以围绕这个问题创建一个可用的证书吗?或者我应该在计算机启动时修改证书值并将当前 IP 地址添加到 SubjectAlternativeName
列表?
根据评论,处理这种情况的最佳方法似乎是在客户端提供自定义证书验证,同时牢记 Patrick Mevzek 评论中的注意事项。
自定义证书验证涉及您编写自己的代码来验证证书中的某些方面。 HttpClientHandler
class 提供了一个
ServerCertificateCustomValidationCallback
属性 您可以使用自己的回调进行设置。
证书首先由 .NET 进行评估,然后此验证的结果作为提示传递给您的回调 SslPolicyErrors
enum along with the certificate. You have several options for correcting the validation error(s). See for example this answer。在回调中,您可以检查提示中的主题替代名称并确保它是 "TestSRV01".
GetNameInfo
method of X509Certificate2
只能用于检索主题备用名称列表中的第一个 DNS 名称,因此如果您要检查的主机名不是第一个,那么您将不得不进行战斗使用 .NET 获取您需要的信息。
我有以下代码来创建自签名证书:
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);
}
我只添加了服务器的DNS名称避免绑定到当前IP地址(测试机在不同的网络中移动)
事实证明,我从客户端连接时需要使用 IP 地址(测试站点上的 DNS 解析不可靠)。
不幸的是,SSL 连接失败并显示此消息:
(Hostname 192.168.0.*** not verified: certificate: sha256/UuUOTTQTCb2wu************************ DN: CN=
我无法将证书绑定到这个地址,而且我也无法使用域名作为连接参数。
我可以围绕这个问题创建一个可用的证书吗?或者我应该在计算机启动时修改证书值并将当前 IP 地址添加到 SubjectAlternativeName
列表?
根据评论,处理这种情况的最佳方法似乎是在客户端提供自定义证书验证,同时牢记 Patrick Mevzek 评论中的注意事项。
自定义证书验证涉及您编写自己的代码来验证证书中的某些方面。 HttpClientHandler
class 提供了一个
ServerCertificateCustomValidationCallback
属性 您可以使用自己的回调进行设置。
证书首先由 .NET 进行评估,然后此验证的结果作为提示传递给您的回调 SslPolicyErrors
enum along with the certificate. You have several options for correcting the validation error(s). See for example this answer。在回调中,您可以检查提示中的主题替代名称并确保它是 "TestSRV01".
GetNameInfo
method of X509Certificate2
只能用于检索主题备用名称列表中的第一个 DNS 名称,因此如果您要检查的主机名不是第一个,那么您将不得不进行战斗使用 .NET 获取您需要的信息。