Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to proper setup HTTPS for NET Core 2.1 using a store certificate

I have generated a certificate using powershell using this suggestion found at Stackoverflow:

New-SelfSignedCertificate -Subject "CN=Test Code Signing" -Type CodeSigningCert -KeySpec "Signature" -KeyUsage "DigitalSignature" -FriendlyName "Test Code Signing" -NotAfter (get-date).AddYears(5)

enter image description here

I have copied and pasted this certificate into Trusted Root Certification Authorities.

My NET Core WebAPI Program.cs is set as follows:

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .UseKestrel(options=> {
            options.Listen(IPAddress.Loopback, 5000);  // http:localhost:5000
            options.Listen(IPAddress.Any, 80);         // http:*:80
            options.Listen(IPAddress.Loopback, 443, listenOptions =>
            {
                //how to use a certificate store here? 
                //listenOptions.UseHttps("certificate.pfx", "password");
                //listenOptions.UseHttps(StoreName.My, "Test Code Signing", allowInvalid: true);
                listenOptions.UseHttps(StoreName.My, "localhost", allowInvalid: true);

            }); 
});

Neither localhost or Test Code Signing worked in this code since they cannot be found. Maybe I am missing something. Tried to follow this MSDN documentation with no luck.

For now the certificate shown on Google Chrome is different from the ones I have in Personal and Trusted Root Certification authorities:

enter image description here

How to setup Kestrel in order to pick a self signed certificate that is trusted by browsers and avoiding blocking messages such as NET::ERR_CERT_AUTHORITY_INVALID?

like image 386
Junior Mayhé Avatar asked Jun 17 '18 17:06

Junior Mayhé


1 Answers

The UseHttps overload you are using doesn't allow you to specific the store location so it defaults to StoreLocation.CurrentUser. You need to do call a method which retrieves the certificate from the store and passes it to the UseHttps method. There's an MSDN article that gives more detail that I've included at the bottom but here's an example (you need to replace 'your common name here' with the certificate common name):

    static void Main(string[] args)
    {
        var host = new WebHostBuilder()
             .UseKestrel(options =>
            {
                options.Listen(IPAddress.Any, 443, listenOptions =>
                {
                    listenOptions.UseHttps(GetHttpsCertificateFromStore());
                    listenOptions.NoDelay = true;
                });

            })
            .Build();
    }

    private static X509Certificate2 GetHttpsCertificateFromStore()
    {
        using (var store = new X509Store(StoreName.My, StoreLocation.LocalMachine))
        {
            store.Open(OpenFlags.ReadOnly);
            var certCollection = store.Certificates;
            var currentCerts = certCollection.Find(X509FindType.FindBySubjectDistinguishedName, "CN=[your common name here]", false);

            if (currentCerts.Count == 0)
            {
                throw new Exception("Https certificate is not found.");
            }

            return currentCerts[0];
        }
    }

https://docs.microsoft.com/bs-latn-ba/azure/service-fabric/service-fabric-tutorial-dotnet-app-enable-https-endpoint

like image 150
Ian Gibson Avatar answered Oct 16 '22 09:10

Ian Gibson