aspnetcore: Host unreachable in https due to weak Http2 cipher

Describe the bug

The browser is not happy with the cipher used for HTTP2 (i guess) ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY and equivalent in chrome

Bad Workaround

only for firefox i managed to go in about:config and disable weak cypher check this actually has an effect

is there a simple way to completely disable HTTP2 via a Kestrel IOptions<> ?

To Reproduce

Steps to reproduce the behavior:

  1. uninstalled ALL sdk
  2. removed folder from program files/user/appdata/temp
  3. install sdk 2.2.105 and 3.0.0-preview3 from https://dot.net
  4. version of ASP.NET Core : the one shipped with preview3
  5. dotnet new webapi -n foo
  6. comment out UseHsts
  7. comment out UseHttpsRedirection()
  8. dotnet run --project foo.csproj
  9. hit the http endpoint => works
  10. hit the https endpoint => rejected

Expected behavior

i tried to :

  • dotnet dev-certs http --clean
  • dotnet dev-certs http --trust
  • delete .vs/
  • change launchSettings.json to anything else
  • removed UseHttpsRedirection()
  • removed UseHsts()
  • not working for IP / dns in the browser

pretty sure all i did was update Vs2019, it was workign 2 weeks ago on the same SDK (or the latest win10 insider - fast ring update)

>dotnet --version
3.0.100-preview3-010431
<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0-preview3-19153-02" />
  </ItemGroup>

</Project>

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 2
  • Comments: 75 (54 by maintainers)

Commits related to this issue

Most upvoted comments

There’s a typo in https://github.com/aspnet/AspNetCore/issues/8952#issuecomment-482499042, but when corrected, this worked:

dotnet dev-certs https --clean
dotnet dev-certs https --trust

Yep. We intend to fix our dev cert for 3.0, but as a temporary workaround you can use the IIS Express development certificate directly from Kestrel.

This only works on Windows (but so far the problem has only been reported there), and requires that you have IIS Express installed and configured (installing VS is sufficient for this). You do not actually have to use IIS Express to host your site, we’re just borrowing it’s development certificate 😃.

First you need to find your IIS Express cert in the user certificate store and get the thumbprint. The followng PowerShell script will do the trick:

dir Cert:\CurrentUser\Root\ | Where { $_.FriendlyName -like "IIS Express*" } | Select Thumbprint

Once you’ve got the thumbprint, you can write a small bit of code in Program.cs to grab that certificate out of the store and use it for Kestrel.

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();

                // Add this section below
                webBuilder.ConfigureKestrel(options =>
                {
                    options.ConfigureHttpsDefaults(ssl =>
                    {
                        // Open the Current User's Trusted Root Certificate store
                        var store = new X509Store(StoreName.Root, StoreLocation.CurrentUser);
                        store.Open(OpenFlags.ReadOnly);

                        // Find the IIS Express Certificate
                        var cert = store.Certificates.Find(X509FindType.FindByThumbprint, "<<put the hex thumbprint value in here>>", validOnly: false);
                        ssl.ServerCertificate = cert.Cast<X509Certificate2>().First();
                    });
                });
            });
}

If you run

dotnet dev-certs http --clean

The powershell script above and then

dotnet dev-certs http --trust

It should unblock you.

@nphmuller

Did you try running the following commands with a preview6 dotnet environment?

dotnet dev-certs https --clean
dotnet dev-certs https --trust

Its likely that you have an old cert. We added logic to upgrade the certificate, but I’m not sure if it made it into preview6 or will be available on preview7.

I have a freshly installed VS2019 Preview 16.2 Preview 2 and this is the first ASP.NET core with Kestrel project that I run and I’m hitting the same issue. I’ve tried the clean/trust commands to refresh the certificate with no change.

dotnet --version 3.0.100-preview-010184

This is an empty project with .ConfigureKestrel() added without any changes

I imagine that’s because you are using docker containers. That’s the location where docker exports the certificate to import it into the container.

@anurse we could add this to the docs I think. I’m not sure the implications cleaning this folder have for the docker folks, but we can ask them.

What I don’t want is to add this to the tool, as its a docker tooling implementation detail and has nothing to do with the tool.

That said, I don’t think we need to change the runtime here so long as we provide details on what to do if you run into this situation in the docs. I’ve filed https://github.com/aspnet/AspNetCore.Docs/issues/13927 to track it.

@anurse The powershell snippet below will create a “aspnetcore compatible” https cert with the addition of Digital Signature. I’ve been trying to repro this on the Win 10 insider builds and I haven’t been able to. Can you get someone on the team to try it out?

More importantly I think we should review the cipher suites offered by IIS and Kestrel. I’m not sure adding the change above is correct, and I would like @blowdart to chime in

function TryCreateAspNetCoreCertUsingPowershell () {
    $ekuOidCollection = [System.Security.Cryptography.OidCollection]::new();
    $ekuOidCollection.Add([System.Security.Cryptography.Oid]::new("1.3.6.1.5.5.7.3.1","Server Authentication"));
    $sanBuilder = [System.Security.Cryptography.X509Certificates.SubjectAlternativeNameBuilder]::new();
    $sanBuilder.AddDnsName("localhost");

    $certificateExtensions = @(
        # Subject Alternative Name
        $sanBuilder.Build($true),        
        # ASP.NET Core OID
        [System.Security.Cryptography.X509Certificates.X509Extension]::new(
            "1.3.6.1.4.1.311.84.1.1",
            [System.Text.Encoding]::ASCII.GetBytes("ASP.NET Core HTTPS development certificate"),
            $false),
        # KeyUsage
        [System.Security.Cryptography.X509Certificates.X509KeyUsageExtension]::new(
            [System.Security.Cryptography.X509Certificates.X509KeyUsageFlags]::KeyEncipherment -bor [System.Security.Cryptography.X509Certificates.X509KeyUsageFlags]::DigitalSignature,
            $true),
        # Enhanced key usage
        [System.Security.Cryptography.X509Certificates.X509EnhancedKeyUsageExtension]::new(
            $ekuOidCollection,
            $true),
        # Basic constraints
        [System.Security.Cryptography.X509Certificates.X509BasicConstraintsExtension]::new($false,$false,0,$true))
    $parameters = @{
        Subject = "localhost";
        KeyAlgorithm = "RSA";
        KeyLength = 2048;
        CertStoreLocation = "Cert:\CurrentUser\My";
        KeyExportPolicy = "Exportable";
        NotBefore = Get-Date;
        NotAfter = (Get-Date).AddYears(1);
        HashAlgorithm = "SHA256";
        Extension = $certificateExtensions;
        SuppressOid = @("2.5.29.14");
        FriendlyName = "ASP.NET Core HTTPS development certificate"
    }
    New-SelfSignedCertificate @parameters
}

@anurse Having read through the issue, but should be doable. Will have to let @blowdart know but if we are just making the key for a more modern key that should be fine. (Again, haven’t read the issue, but I imagine that’s it).