Chrome reports ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY connecting to local web server over HTTPS
Solution 1
Http/2 requirements as per https://httpwg.org/specs/rfc7540.html#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?
Solution 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.
Related videos on Youtube
NathanAldenSr
Updated on September 18, 2022Comments
-
NathanAldenSr over 1 year
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:
- 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
- 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
- Added a
HOSTS
file entry formyapp.local
that points to127.0.0.1
- Created an IIS 8.5 application that is bound to the
myapp.local
domain and listens for HTTPS requests only - 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
-
NathanAldenSr almost 9 yearsBefore 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. -
Drifter104 almost 9 yearsPrehaps not the cipher but the ssl/tls version that is enabled. Have you got tls v1.0 or lower enabled?
-
NathanAldenSr almost 9 yearsI 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?
-
Drifter104 almost 9 yearsstackoverflow.com/questions/31746620/… may help. Apparently disabling spdy in browser is the way to go
-
NathanAldenSr almost 9 yearsThanks for the link; I missed that in my initial search. Thing is, I don't really want to disable HTTP/2. I'd like to use it in production for my web application, if I can. Obviously, I won't have control over my users' browser so disabling it client-side isn't an option.
-
Drifter104 almost 9 yearsspdy is not http/2 however I don't know if you can disable spdy in chrome without also disabling. the flag to lauch chrome without spdy is --use-spdy=off you can then use the http2 indicator extension in chrome to test if turning one off turns the other off. This is an application issue. I don't think you'll be able to support both until chrome is patched to switch to http/2 if it is present
-
NathanAldenSr almost 9 yearsI added a Fiddler trace that could help someone experienced with these issues diagnose the problem. Until then, it looks like my only option is to disable SPDY and HTTP/2 in IIS 10. :(
-
ahwm almost 7 yearsIIS 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. :)
-
Vin Shahrdar almost 6 years@ahwm Thanks! After clicking "Best Practices" in IIS Crypto and restarting my machine multiple times the error was gone.
- Generated a self-signed certificate intended for use as a trusted root CA using the following command:
-
Håkan Lindqvist almost 9 yearsAdjusting your cipher suites (possibly just the ordering) to meet Http/2 specs should solve the problem properly. (See separate answer)
-
NathanAldenSr almost 9 yearsThis 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 almost 9 yearsI 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?
-
Peter Hahndorf almost 9 years@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. -
NathanAldenSr almost 9 yearsI 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 getERR_CONNECTION_RESET
. Could this have anything to do with the certificates themselves? -
Håkan Lindqvist almost 9 years@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
). -
NathanAldenSr almost 9 yearsThank you for the starting point. I've updated my answer to show what worked for me.
-
Bart Verkoeijen almost 8 yearsNote, 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. -
Håkan Lindqvist almost 8 years@BartVerkoeijen Good point, I added a note about this. Thanks.
-
Sebastian Krysmanski about 7 yearsIt seems you have to restart Windows for these changes to take effect. Just calling
iisreset
didn't do the trick for me. -
Khalid Rahaman about 5 yearsi used IISCrypto to move TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256_P256 to the top of the list, rebooted and it worked. Thanks @HåkanLindqvist