19

Summary

Chrome is reporting ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY when I try and connect to my local web server over HTTPS. I am almost certain this problem has to do with my recent Windows 10 upgrade, but I don't know how to fix it.

What worked

Here's the chain of events, with me having Windows 8.1 Pro installed at the start:

  1. Generated a self-signed certificate intended for use as a trusted root CA using the following command: makecert.exe -pe -ss Root -sr LocalMachine -n "CN=local, OU=development" -r -a sha512 -e 01/01/2020
  2. Generated an application-specific certificate from the trusted root CA: makecert.exe -pe -ss My -sr LocalMachine -n "CN=myapp.local, OU=Development" -is Root -ir LocalMachine -in local -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12 -a sha512 -e 01/01/2020 -sky -eku 1.3.6.1.5.5.7.3.1
  3. Added a HOSTS file entry for myapp.local that points to 127.0.0.1
  4. Created an IIS 8.5 application that is bound to the myapp.local domain and listens for HTTPS requests only
  5. Assigned the myapp.local certificate to the web site

With this setup, I had no trouble accessing my local web site from Chrome without any certificate or security warnings. The browser displayed the green padlock, as expected.

What doesn't work

Recently, I upgraded to Windows 10. I did not know at the time that Windows 10 ships with IIS 10, which supports HTTP/2. Now, when I try and access my local web sites with Chrome, I receive an ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY error. I should note that the same request sent from Edge does not result in an error and does use HTTP/2 for the connection. A cursory Google search didn't turn up anything promising, except to hint that the problem might be that HTTP/2 or Chrome is strict about what ciphers it will accept in SSL certificates.

Thinking it may be an issue with enabled cipher suites in Windows (but not being an expert in such things), I downloaded the latest version of IIS Crypto. I clicked the Best Practices button, clicked Apply, and restarted my machine.

IIS Crypto reports these settings as "best practices":

  • Enabled protocols: TLS 1.0, TLS 1.1, TLS 1.2
  • Enabled ciphers: Triple DES 168, AES 128/128, AES 256/256
  • Enabled hashes: MD5, SHA, SHA 256, SHA 384, SHA 512
  • Enabled key exchanges: Diffie-Hellman, PKCS, ECDH
  • SSL cipher suite order:

    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P521
    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384
    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256
    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P521
    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P284
    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P256
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P521
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P284
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_P521
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_P284
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_P256
    TLS_RSA_WITH_AES_256_GCM_SHA384
    TLS_RSA_WITH_AES_128_GCM_SHA256
    TLS_RSA_WITH_AES_256_CBC_SHA256
    TLS_RSA_WITH_AES_256_CBC_SHA
    TLS_RSA_WITH_AES_128_CBC_SHA256
    TLS_RSA_WITH_AES_128_CBC_SHA
    TLS_RSA_WITH_3DES_EDE_CBC_SHA

I'll also add that the browser application I'm developing does not need to be usable from Windows XP. I know there are some issues about Windows XP not supporting newer protocols.

Detailed information about the HTTPS negotiation

I decided to use Fiddler to intercept the HTTPS negotiation. Here's what Fiddler reported about the request:

Version: 3.3 (TLS/1.2)
Random: 6B 47 6D 2B BC AE 00 F1 1D 41 57 7C 46 DB 35 19 D7 EF A9 2B B1 D0 81 1D 35 0D 75 7E 4C 05 14 B0
"Time": 2/1/1993 9:53:15 AM
SessionID: 98 2F 00 00 15 E7 C5 70 12 70 CD A8 D5 C7 D4 4D ED D8 1F 42 F9 A8 2C E6 67 13 AD C0 47 C1 EA 04
Extensions: 
    server_name myapp.local
    extended_master_secret  empty
    SessionTicket   empty
    signature_algs  sha512_rsa, sha512_ecdsa, sha384_rsa, sha384_ecdsa, sha256_rsa, sha256_ecdsa, sha224_rsa, sha224_ecdsa, sha1_rsa, sha1_ecdsa
    status_request  OCSP - Implicit Responder
    NextProtocolNego    empty
    SignedCertTimestamp (RFC6962)   empty
    ALPN        http/1.1, spdy/3.1, h2-14, h2
    channel_id(GoogleDraft) empty
    ec_point_formats    uncompressed [0x0]
    elliptic_curves secp256r1 [0x17], secp384r1 [0x18]
Ciphers: 
    [C02B]  TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
    [C02F]  TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
    [009E]  TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
    [CC14]  TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
    [CC13]  TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
    [CC15]  TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
    [C00A]  TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
    [C014]  TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA
    [0039]  TLS_DHE_RSA_WITH_AES_256_SHA
    [C009]  TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
    [C013]  TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA
    [0033]  TLS_DHE_RSA_WITH_AES_128_SHA
    [009C]  TLS_RSA_WITH_AES_128_GCM_SHA256
    [0035]  TLS_RSA_AES_256_SHA
    [002F]  TLS_RSA_AES_128_SHA
    [000A]  SSL_RSA_WITH_3DES_EDE_SHA
    [00FF]  TLS_EMPTY_RENEGOTIATION_INFO_SCSV

Compression: 
    [00]    NO_COMPRESSION

and the response:

Version: 3.3 (TLS/1.2)
SessionID:  98 2F 00 00 15 E7 C5 70 12 70 CD A8 D5 C7 D4 4D ED D8 1F 42 F9 A8 2C E6 67 13 AD C0 47 C1 EA 04
Random:     55 C6 8D BF 78 72 88 41 34 BD B4 B8 DA ED D3 C6 20 5C 46 D6 5A 81 BD 6B FC 36 23 0B 15 21 5C F6
Cipher:     TLS_RSA_WITH_AES_128_GCM_SHA256 [0x009C]
CompressionSuite:   NO_COMPRESSION [0x00]
Extensions:
        ALPN        h2
        0x0017      empty
        renegotiation_info  00
        server_name empty

What's working

Based on Håkan Lindqvist's answer, and the very detailed and apparently-thoroughly-researched answer here, I reconfigured IIS Crypto with the following settings, which eliminated the Chrome error:

  • Enabled protocols: TLS 1.0, TLS 2.0, TLS 3.0
  • Enabled ciphers: AES 128/128, AES 256/256
  • Enabled hashes: SHA, SHA 256, SHA 384, SHA 512
  • Enabled key exchanges: Diffie-Hellman, PKCS, ECDH
  • SSL cipher suite order:

    TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
    TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
    TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384_P521
    TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384_P384
    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256_P521
    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256_P384
    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256_P256
    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384_P521
    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384_P384
    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256_P521
    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256_P384
    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256_P256
    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA_P521
    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA_P384
    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA_P256
    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA_P521
    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA_P384
    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA_P256
    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P521
    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384
    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P521
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P384
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256
    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P521
    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384
    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P256
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_P521
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_P384
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_P256
    TLS_RSA_WITH_AES_256_GCM_SHA384
    TLS_RSA_WITH_AES_128_GCM_SHA256
    TLS_RSA_WITH_AES_256_CBC_SHA256
    TLS_RSA_WITH_AES_128_CBC_SHA256
    TLS_RSA_WITH_AES_256_CBC_SHA
    TLS_RSA_WITH_AES_128_CBC_SHA

  • Before anyone points out the obvious: Yes, I am aware makecert.exe is deprecated. I only use it for development scenarios like this because it is the easiest option that [used to?] works. – NathanAldenSr Aug 8 '15 at 22:50
  • Prehaps not the cipher but the ssl/tls version that is enabled. Have you got tls v1.0 or lower enabled? – Drifter104 Aug 8 '15 at 22:55
  • I updated the question to include what I did with IIS Crypto to control those settings. Do you know if the settings are too permissive for HTTP/2 and Chrome? – NathanAldenSr Aug 8 '15 at 23:00
  • stackoverflow.com/questions/31746620/… may help. Apparently disabling spdy in browser is the way to go – Drifter104 Aug 8 '15 at 23:05
  • 1
    IIS Crypto "Best Practices" in version 2.0 fixed this error for me. I tried using the suite order you specified but had no effect. Apparently it's been fixed in either Windows or IIS Crypto somewhere along the way. :) – ahwm Jun 9 '17 at 21:06
20

Http/2 requirements as per https://http2.github.io/http2-spec/#rfc.section.9.2.2 :

9.2.2 TLS 1.2 Cipher Suites

A deployment of HTTP/2 over TLS 1.2 SHOULD NOT use any of the cipher suites that are listed in the cipher suite black list (Appendix A).

Endpoints MAY choose to generate a connection error (Section 5.4.1) of type INADEQUATE_SECURITY if one of the cipher suites from the black list is negotiated. A deployment that chooses to use a black-listed cipher suite risks triggering a connection error unless the set of potential peers is known to accept that cipher suite.

Implementations MUST NOT generate this error in reaction to the negotiation of a cipher suite that is not on the black list. Consequently, when clients offer a cipher suite that is not on the black list, they have to be prepared to use that cipher suite with HTTP/2.

The black list includes the cipher suite that TLS 1.2 makes mandatory, which means that TLS 1.2 deployments could have non-intersecting sets of permitted cipher suites. To avoid this problem causing TLS handshake failures, deployments of HTTP/2 that use TLS 1.2 MUST support TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [TLS-ECDHE] with the P-256 elliptic curve [FIPS186].

Note that clients might advertise support of cipher suites that are on the black list in order to allow for connection to servers that do not support HTTP/2. This allows servers to select HTTP/1.1 with a cipher suite that is on the HTTP/2 black list. However, this can result in HTTP/2 being negotiated with a black-listed cipher suite if the application protocol and cipher suite are independently selected.


Your negotiated cipher TLS_RSA_WITH_AES_128_GCM_SHA256 is in the above mentioned (and linked) Http/2 blacklist.

I believe you will want to adjust your cipher suites (ordering?) to meet the above requirements. Maybe simply putting TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 with the NIST P-256 elliptic curve (identified as TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256_P256 on Windows) at the top of the list, or at least before anything included in the blacklist?

  • I will try this immediately and let you know how it turns out. Thanks for the detailed answer! :) Honestly, it seems like this cipher suite issue may make using HTTP/2 at the same time as HTTP/1.1 really tricky, if not impossible, until browsers are guaranteed to work around the inconsistencies. IPv4/IPv6, anyone? – NathanAldenSr Aug 9 '15 at 14:26
  • I compared IIS Crypto's "best practices" cipher suite list against the blacklist. What I found is that all the best-practice TLS_RSA cipher suites are in the blacklist. I disabled them all and rebooted. However, now I cannot establish a secure connection to my local web site with any browser. I just get ERR_CONNECTION_RESET. Could this have anything to do with the certificates themselves? – NathanAldenSr Aug 9 '15 at 14:54
  • @NathanAldenSr I don't think you need to remove the blacklisted ciphers (they may be useful for compatibility purposes for HTTP/1.x clients) as long as non-blacklisted ciphers have higher priority. In particular the one mentioned that all HTTP/2 deployments MUST support (TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256). – Håkan Lindqvist Aug 9 '15 at 15:04
  • 1
    Thank you for the starting point. I've updated my answer to show what worked for me. – NathanAldenSr Aug 9 '15 at 15:44
  • 1
    Note, the HTTP/2 spec says it's TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 with the P-256 elliptic curve [FIPS186], meaning the string: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256_P256 for Windows. – Bart Verkoeijen Jul 11 '16 at 10:26
2

Here's some PowerShell I created to temporarily disable HTTP/2 in IIS:

Set-ItemProperty -Path HKLM:\System\CurrentControlSet\Services\HTTP\Parameters -Name EnableHttp2Tls -Value 0 -Type DWord
Set-ItemProperty -Path HKLM:\System\CurrentControlSet\Services\HTTP\Parameters -Name EnableHttp2Cleartext -Value 0 -Type DWord

I'm making this an answer since disabling HTTP/2 seems to be the only "solution" to the problem. I won't accept it, though, since I'd really like to use HTTP/2 in IIS 10 reliably with all browsers.

  • Adjusting your cipher suites (possibly just the ordering) to meet Http/2 specs should solve the problem properly. (See separate answer) – Håkan Lindqvist Aug 9 '15 at 3:58
  • 3
    It seems you have to restart Windows for these changes to take effect. Just calling iisreset didn't do the trick for me. – Sebastian Krysmanski May 3 '17 at 6:20
-1

Just get a certificate from a proper CA, there are free ones (StartSSL) and it doesn't take that much longer to get one.

When using a proper cert I had no problem with using IIS 10 on Windows 10 and HTTP/2 with Chrome.

  • 1
    This won't work for me, unfortunately. I have automated scripts that generate these certificates for both local and development environments, and every developer's workstation needs them. Additionally, I want the flexibility to be able to change host names without having to go back to a third-party to get new certificates. – NathanAldenSr Aug 9 '15 at 14:26
  • @NathanAldenSr - I understand. For a fully scripted process we are using a local internal CA. It would be nice to know whether the makecert.exe self-created certs are the problem. I never used makecert.exe, I always thought a local CA is a much cleaner solution. – Peter Hahndorf Aug 9 '15 at 14:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.