Repository navigation
Perfect Forward Secrecy: Default ciphers and Chrome #818
Description
Activity
The docs state it as supported: https://iojs.org/api/tls.html#tls_perfect_forward_secrecy
Did you run your server against ssllabs's tests?
Yes, PFS is supported by io.js TLS. My point is that the default ciphers in io.js will not result in PFS with Chrome's preferences (see the ssllabs link above and compare the cipher order there).
I have tested with and without the suggested change above and before the change, Chrome is without PFS, and after it is. The reason is that Chrome goes for GCM (to do the encryption and authentication in one go rather than do the authentication separately) which the default ciphers do not yet include support for.
I was running against ssllab's tests and that's actually how I came across this. I was surprised at first, because PFS was working in Firefox but not in Chrome.
cc @indutny?
Running this config
{ key : "path" cert : "path" ca : "path" dhparam : "path" honorCipherOrder : true }
against ssllabs shows that Chrome indeed doesn't pick an ECDHE cipher:
Android 2.3.7 TLS 1.0 TLS_RSA_WITH_RC4_128_SHA (0x5) Android 4.0.4 TLS 1.0 TLS_ECDHE_RSA_WITH_RC4_128_SHA (0xc011) Android 4.1.1 TLS 1.0 TLS_ECDHE_RSA_WITH_RC4_128_SHA (0xc011) Android 4.2.2 TLS 1.0 TLS_ECDHE_RSA_WITH_RC4_128_SHA (0xc011) Android 4.3 TLS 1.0 TLS_ECDHE_RSA_WITH_RC4_128_SHA (0xc011) Android 4.4.2 TLS 1.2 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027) BingBot Dec 2013 TLS 1.0 TLS_RSA_WITH_RC4_128_SHA (0x5) BingPreview Jun 2014 TLS 1.0 TLS_RSA_WITH_RC4_128_SHA (0x5) Chrome 39 / OS X TLS 1.2 TLS_RSA_WITH_AES_128_GCM_SHA256 (0x9c) Firefox 31.3.0 ESR / Win 7 TLS 1.2 TLS_ECDHE_RSA_WITH_RC4_128_SHA (0xc011) Firefox 34 / OS X TLS 1.2 TLS_ECDHE_RSA_WITH_RC4_128_SHA (0xc011) Googlebot Jun 2014 TLS 1.0 TLS_ECDHE_RSA_WITH_RC4_128_SHA (0xc011) IE 6 / XP Protocol or cipher suite mismatch IE 7 / Vista TLS 1.0 TLS_RSA_WITH_RC4_128_SHA (0x5) IE 8 / XP TLS 1.0 TLS_RSA_WITH_RC4_128_SHA (0x5) IE 8-10 / Win 7 TLS 1.0 TLS_RSA_WITH_RC4_128_SHA (0x5) IE 11 / Win 7 TLS 1.2 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027) IE 11 / Win 10 Preview TLS 1.2 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027) IE 11 / Win 8.1 TLS 1.2 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027) IE Mobile 10 / Win Phone 8.0 TLS 1.0 TLS_RSA_WITH_RC4_128_SHA (0x5) IE Mobile 11 / Win Phone 8.1 TLS 1.2 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027) Java 6u45 TLS 1.0 TLS_RSA_WITH_RC4_128_SHA (0x5) Java 7u25 TLS 1.0 TLS_ECDHE_RSA_WITH_RC4_128_SHA (0xc011) Java 8b132 TLS 1.2 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027) OpenSSL 0.9.8y TLS 1.0 TLS_RSA_WITH_RC4_128_SHA (0x5) OpenSSL 1.0.1h TLS 1.2 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027) Safari 5.1.9 / OS X 10.6.8 TLS 1.0 TLS_ECDHE_RSA_WITH_RC4_128_SHA (0xc011) Safari 6 / iOS 6.0.1 TLS 1.2 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027) Safari 7 / iOS 7.1 TLS 1.2 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027) Safari 8 / iOS 8.0 Beta TLS 1.2 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027) Safari 6.0.4 / OS X 10.8.4 TLS 1.0 TLS_ECDHE_RSA_WITH_RC4_128_SHA (0xc011) Safari 7 / OS X 10.9 TLS 1.2 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027) Yahoo Slurp Jun 2014 TLS 1.2 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027) YandexBot Sep 2014 TLS 1.2 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027)Removing
AES128-GCM-SHA256from the default ciphers seems to be enough to let Chrome chooseTLS_ECDHE_RSA_WITH_AES_256_CBC_SHA. Any special reason to keep that cipher?@jorangreef did you by chance test with
honorCipherOrderenabled? My tests show that Chrome negotiates ECDHE fine without it, but with it set, I get the RSA cipher as seen above.- addedtlsIssues and PRs related to the tls subsystem.Issues and PRs related to the tls subsystem.
on Feb 13, 2015 @silverwind Yes, well spotted. I was testing with honorCipherOrder enabled, and I also get ECDHE on Chrome with that disabled.
honorCipherOrder forces Chrome to pick AES128-GCM-SHA256 over the cipher including ECDHE that it would pick through HIGH.
Swapping AES128-GCM-SHA256 with HIGH in the default ciphers, i.e. ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:HIGH:AES128-GCM-SHA256:RC4:!MD5:!aNULL would lead to ECDHE on Chrome even with honorCipherOrder enabled.
But AES128-GCM-SHA256 is very good and should be in the default ciphers. The real problem is that we don't have enough ECDHE options coming through in ECDHE-RSA-AES128-SHA256.
Adding ECDHE-RSA-AES128-GCM-SHA256 would do the trick.
In the PR, I've been suggested this explicit list: https://github.com/proxy/gist.github.com/indutny/344b7ebd245068ffd1d6 , it lists
AES128-GCM-SHA256pretty low, so I think it should solve the issue as well.There're quite a few options we have on improving the cipher list and it seems there's no universally accepted 'secure' list. I'll test more later.
Out of curiosity, has anyone checked what the size of the handshake packet is before and after?
@silverwind I checked Fedor's explicit ciphers list and it's good, it just does not yet get FS with ssllab's tests for Safari and modern IE which are reference browsers:
https://www.ssllabs.com/ssltest/viewClient.html?name=Safari&version=8&platform=iOS%208.0%20Beta
https://www.ssllabs.com/ssltest/viewClient.html?name=Safari&version=6&platform=iOS%206.0.1
https://www.ssllabs.com/ssltest/viewClient.html?name=IE&version=11&platform=Win%207
https://www.ssllabs.com/ssltest/viewClient.html?name=IE%20Mobile&version=11&platform=Win%20Phone%208.1@bnoordhuis Do you mean for all combinations of cipher negotiations and using explicit ciphers vs the default? I haven't checked but if it's just for adding ECDHE-RSA-AES128-GCM-SHA256 to the defaults (for A+ on ssllabs with honorCipherOrder enabled and removing RC4) then surely there would be no change as that cipher just uses GCM compared to ECDHE-RSA-AES128-SHA256? I guess one would really have to check.
@jorangreef your ssllabs results contain RC4 ciphers, which my cipher list does not really have. Are you sure you was using the right configuration?
Aaaah... Gosh, it was a support list. Sorry.
@jorangreef it is rather odd that it doesn't select PFS ciphers for you. This is a test of this ciphers list on my blog: https://www.ssllabs.com/ssltest/analyze.html?d=blog.indutny.com (ignore the B grade, it is some weird bud bug).
Results look promising with @indutny's list:
Android 2.3.7 TLS 1.0 TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x33) Android 4.0.4 TLS 1.0 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014) Android 4.1.1 TLS 1.0 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014) Android 4.2.2 TLS 1.0 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014) Android 4.3 TLS 1.0 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014) Android 4.4.2 TLS 1.2 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027) BingBot Dec 2013 TLS 1.0 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014) BingPreview Jun 2014 TLS 1.0 TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x39) Chrome 39 / OS X TLS 1.2 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014) Firefox 31.3.0 ESR / Win 7 TLS 1.2 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014) Firefox 34 / OS X TLS 1.2 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014) Googlebot Jun 2014 TLS 1.0 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014) IE 6 / XP Protocol or cipher suite mismatch IE 7 / Vista TLS 1.0 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014) IE 8 / XP TLS 1.0 TLS_RSA_WITH_3DES_EDE_CBC_SHA (0xa) IE 8-10 / Win 7 TLS 1.0 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014) IE 11 / Win 7 TLS 1.2 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027) IE 11 / Win 10 Preview TLS 1.2 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027) IE 11 / Win 8.1 TLS 1.2 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027) IE Mobile 10 / Win Phone 8.0 TLS 1.0 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014) IE Mobile 11 / Win Phone 8.1 TLS 1.2 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027) Java 6u45 TLS 1.0 TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x33) Java 7u25 TLS 1.0 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013) Java 8b132 TLS 1.2 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027) OpenSSL 0.9.8y TLS 1.0 TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x39) OpenSSL 1.0.1h TLS 1.2 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027) Safari 5.1.9 / OS X 10.6.8 TLS 1.0 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014) Safari 6 / iOS 6.0.1 TLS 1.2 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027) Safari 7 / iOS 7.1 TLS 1.2 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027) Safari 8 / iOS 8.0 Beta TLS 1.2 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027) Safari 6.0.4 / OS X 10.8.4 TLS 1.0 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014) Safari 7 / OS X 10.9 TLS 1.2 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027) Yahoo Slurp Jun 2014 TLS 1.2 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027) YandexBot Sep 2014 TLS 1.2 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027)6 remaining items
@indutny, is your blog using honorCipherOrder? I ran my test with that enabled, assuming the pull request linked to from here was going to enable it, and that we need to make sure the ciphers list is in the right order. Could that be the difference?
@silverwind yes I saw that. I tried using just TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 and TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (for different reference versions of IE and Safari) but I didn't get FS on all of them (reference browsers that is). I think we need to convert that suite format into the same format as Fedor's ciphers.
Here's a sample server setup to test the ciphers:
https://github.com/proxy/gist.github.com/jorangreef/781417d83a6e4669ad38
Updated #826, now has the correct format for Fedor's list:
'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA256:ECDHE-ECDSA-AES256-SHA256:ECDHE-RSA-AES256-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA256:DHE-RSA-AES256-SHA256:AES256-GCM-SHA384:AES256-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:DES-CBC3-SHA'@indutny, I noticed the ssllabs report for your blog shows a cipher suite mismatch for Java6u45?
@jorangreef your test setup doesn't include a
dhparam? Afaik, that shouldn't influence cipher selection, but maybe that's the reason for the different results?@silverwind thanks, I didn't realize that. Without dhparam, the implicit ciphers in the gist still get an A+. Even with dhparam, the explicit ciphers in the gist still do not get forward secrecy on IE and Safari. Also, if we can get an A+ without DHE that would be better due to the overhead of DHE. I updated the gist though to include dhparam. Perhaps the default ciphers don't really need DHE anymore?
A+ without DHE
I don't think that's possible, also we'd drop Android 2.3 I think, which is still in widespread use.
That's what I would have thought, but all the reference browsers support ECDHE, so it is actually possible to get an A+ without having to even have any DHE ciphers at all, which means the default list can save on alot of DHE overhead (unless some people really need DHE for other purposes, and then they can just add to the default). If you look through the reference browser list on the report you will see they all use ECDHE. SSL Labs is basically not forcing anyone to support DHE anymore I think.
Still, I think it's not time yet to remove DHE. I'd do that in an future update to remove TLS 1.0 and 1.1 along with SHA1. Probably sometimes in 2016, when Chrome will start warning on SHA1.
Reading https://tools.ietf.org/html/draft-ietf-uta-tls-bcp-09 which is under IESG review now, DHE is still in the recommended cipher list, so I think it is better to be included in the default list. But as it needs more than 2048bits. I don't mind to make a patch to check its key length.
I also think it is better to specify prohibited cipher lists explicitly such as!RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSSto show our cipher policy.@shigeki I'm -1 for query. It is much better to explicitly tell which ciphers we are using.
@indutny Oh, I missed some words. I meant that prohibited ciphers should be added in the end of the list. It shows users that do not use RC4, NULL and other low security ciphers as described in 4.1. General Guidelines of TLS BCP.
For example, it is
'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA256:ECDHE-ECDSA-AES256-SHA256:ECDHE-RSA-AES256-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA256:DHE-RSA-AES256-SHA256:AES256-GCM-SHA384:AES256-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:DES-CBC3-SHA:!RC4:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS'Yeah, my idea was that there is no point in it when listing the ciphers explicitly. There is no way anything could get through.
@jorangreef #826 was merged and should be available next release, you can close this issue :)
I assumed that with the right OpenSSL and with default ciphers, that a connection from Chrome would negotiate using ECDHE.
The default ciphers are: ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL
But I think that with those Chrome settles for AES128-GCM-SHA256, see: https://www.ssllabs.com/ssltest/viewClient.html?name=Chrome&version=39&platform=OS%20X.
Adding ECDHE-RSA-AES128-GCM-SHA256 to the default ciphers list would fix this.
I don't know if this is an issue or not, but I think it would be great if io.js servers supported perfect forward secrecy on most major browsers out of the box.