如何使用商店证书为NET Core 2.1正确设置HTTPS

时间:2018-06-17 17:02:12

标签: c# https ssl-certificate asp.net-core-webapi kestrel-http-server

我使用在PowerSoverflow上找到的这个建议使用powershell生成了证书:

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

我已将此证书复制并粘贴到受信任的根证书颁发机构。

我的.NET Core WebAPI Program.cs设置如下:

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

            }); 
});

localhost 测试代码签名都未在此代码中工作,因为无法找到它们。也许我错过了什么。试图按照这个MSDN文档,没有运气。

目前,Google Chrome上显示的证书与个人受信任的根证书颁发机构中的证书不同:

enter image description here

如何设置Kestrel以选择受浏览器信任的自签名证书并避免阻止NET::ERR_CERT_AUTHORITY_INVALID等消息?

3 个答案:

答案 0 :(得分:1)

此方法对我有用:

private static X509Certificate2 LoadCertificate(string p_storeName, string p_storeLocation, string p_Host, string p_FilePath, string p_Password, IHostingEnvironment environment)
{
  if (p_storeName != "" && p_storeLocation != "")
  {
      using (var store = new X509Store(p_storeName, Enum.Parse<StoreLocation>(p_storeLocation)))
       {
           store.Open(OpenFlags.ReadOnly);

            bool validOnly = false;
            if (environment.IsDevelopment() == true) { validOnly = false; }
            else
            {
                if (p_Host == "localhost") { validOnly = false; }
                else { validOnly = true; }
            }

            var certificate = store.Certificates.Find(
            X509FindType.FindBySubjectName,p_Host,validOnly: validOnly);

            if (certificate.Count == 0)
            {
                throw new InvalidOperationException($"Certificate not found for {p_Host}.");
            }
                 return certificate[0];
            }
       }

       if (p_FilePath != "" && p_Password != "")
       {
          return new X509Certificate2(p_FilePath, p_Password);
       }
       throw new InvalidOperationException("No valid certificate configuration found for the current endpoint.");
    }

答案 1 :(得分:0)

您正在使用的UseHttps重载不允许您指定商店位置,因此默认为StoreLocation.CurrentUser。您需要调用一个方法,该方法从存储中检索证书并将其传递给UseHttps方法。 MSDN文章的底部提供了更多细节,但这是一个示例(您需要将“您的通用名称”替换为证书通用名称):

    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

答案 2 :(得分:0)

我认为您应该(首先)创建一个受信任的本地证书,(第二个)将其与您的ip和端口相关联,(第三个)您应该使用“ localhost”(为其创建证书的“ CN”)在您的浏览器中,而不是回送IP。

PowerShell中的以下命令(以管理员身份运行)将创建根证书及其关联的受信任证书:

1.- We create a new root trusted cert:
$rootCert = New-SelfSignedCertificate -Subject 'CN=TestRootCA,O=TestRootCA,OU=TestRootCA' -KeyExportPolicy Exportable -KeyUsage CertSign,CRLSign,DigitalSignature -KeyLength 2048 -KeyUsageProperty All -KeyAlgorithm 'RSA' -HashAlgorithm 'SHA256'  -Provider 'Microsoft Enhanced RSA and AES Cryptographic Provider'

2.- We create the cert from the root trusted cert chain:
New-SelfSignedCertificate -DnsName "localhost" -CertStoreLocation "cert:\LocalMachine\My" -Signer $rootCert -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.1") -Provider "Microsoft Strong Cryptographic Provider" -HashAlgorithm "SHA256" -NotAfter (Get-Date).AddYears(10)

3.- We copy the thumbprint returned by the last command

4.- (If neccesary) We remove the last association ip/port/cert:
netsh http delete sslcert ipport=0.0.0.0:443

5.- We associate the new certificate with any ip and port 443 (the appid value does not matter, is any valid guid):
netsh http add sslcert ipport=0.0.0.0:443 appid='{214124cd-d05b-4309-9af9-9caa44b2b74a}' certhash=here_the_copied_thumbprint

6.- Now, you must drag and drop the TestRootCA from Personal/Certificates folder to Trusted Root Certification Authorities/Certificates.

这些命令还解决了Google Chrome稍后返回的错误 ERR_CERT_WEAK_SIGNATURE_ALGORITHM ,因为证书是使用SHA1而不是SHA256创建的。

相关问题