简体   繁体   中英

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).

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).

Unfortunately, the SSL connection fails with this message:

(Hostname 192.168.0.*** not verified: certificate: 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?

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.

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.

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. 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".

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM