Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Perfect Forward Secrecy: Default ciphers and Chrome #818

Closed
jorangreef opened this issue Feb 12, 2015 · 34 comments
Closed

Perfect Forward Secrecy: Default ciphers and Chrome #818

jorangreef opened this issue Feb 12, 2015 · 34 comments
Labels
tls Issues and PRs related to the tls subsystem.

Comments

@jorangreef
Copy link
Contributor

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.

@silverwind
Copy link
Contributor

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?

@jorangreef
Copy link
Contributor Author

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.

@Fishrock123
Copy link
Contributor

cc @indutny?

@silverwind
Copy link
Contributor

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)

@silverwind
Copy link
Contributor

Removing AES128-GCM-SHA256 from the default ciphers seems to be enough to let Chrome choose TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA. Any special reason to keep that cipher?

@silverwind
Copy link
Contributor

@jorangreef did you by chance test with honorCipherOrder enabled? My tests show that Chrome negotiates ECDHE fine without it, but with it set, I get the RSA cipher as seen above.

@brendanashworth brendanashworth added the tls Issues and PRs related to the tls subsystem. label Feb 13, 2015
@jorangreef
Copy link
Contributor Author

@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.

@silverwind
Copy link
Contributor

In the PR, I've been suggested this explicit list: https://gist.github.com/indutny/344b7ebd245068ffd1d6 , it lists AES128-GCM-SHA256 pretty 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.

@bnoordhuis
Copy link
Member

Out of curiosity, has anyone checked what the size of the handshake packet is before and after?

@jorangreef
Copy link
Contributor Author

@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.

@indutny
Copy link
Member

indutny commented Feb 13, 2015

@jorangreef your ssllabs results contain RC4 ciphers, which my cipher list does not really have. Are you sure you was using the right configuration?

@indutny
Copy link
Member

indutny commented Feb 13, 2015

Aaaah... Gosh, it was a support list. Sorry.

@indutny
Copy link
Member

indutny commented Feb 13, 2015

@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).

@silverwind
Copy link
Contributor

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)

@silverwind
Copy link
Contributor

@jorangreef Safari and IE11 get TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, which has FS.

@silverwind
Copy link
Contributor

Out of curiosity, has anyone checked what the size of the handshake packet is before and after?

The "Server Hello" length doesn't change when comparing the current default to Fedor's list with honorCipherOrder, it's 2762 bytes in both cases.

@bnoordhuis
Copy link
Member

Not to derail the discussion further, but making the handshake fit in a single TCP packet could cut handshake times dramatically, particularly with short-lived connections.

@silverwind
Copy link
Contributor

I think the chosen cipher has no influence on length at all, it's just 4 bytes. Most of the packet length is probably caused by key/cert size.

@silverwind
Copy link
Contributor

Looks like the packet I'm dissecting here has a handshake length of 89 bytes, and the certifcate content is concatenated into it, making it 2762 in total.

So my conclusion would be that it's in the user's hand if he wants to compromise on security by using a weak cert (and fitting it in a single packet).

@bnoordhuis
Copy link
Member

Ah, that makes sense. I was wondering why it was so big.

@jorangreef
Copy link
Contributor Author

@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.

@jorangreef
Copy link
Contributor Author

Here's a sample server setup to test the ciphers:

https://gist.github.com/jorangreef/781417d83a6e4669ad38

@silverwind
Copy link
Contributor

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'

@jorangreef
Copy link
Contributor Author

@indutny, I noticed the ssllabs report for your blog shows a cipher suite mismatch for Java6u45?

@silverwind
Copy link
Contributor

@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?

@jorangreef
Copy link
Contributor Author

@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?

@silverwind
Copy link
Contributor

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.

@jorangreef
Copy link
Contributor Author

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.

@silverwind
Copy link
Contributor

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.

@shigeki
Copy link
Contributor

shigeki commented Feb 13, 2015

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 !DSS to show our cipher policy.

@indutny
Copy link
Member

indutny commented Feb 13, 2015

@shigeki I'm -1 for query. It is much better to explicitly tell which ciphers we are using.

@shigeki
Copy link
Contributor

shigeki commented Feb 14, 2015

@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'

@indutny
Copy link
Member

indutny commented Feb 14, 2015

Yeah, my idea was that there is no point in it when listing the ciphers explicitly. There is no way anything could get through.

@silverwind
Copy link
Contributor

@jorangreef #826 was merged and should be available next release, you can close this issue :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
tls Issues and PRs related to the tls subsystem.
Projects
None yet
Development

No branches or pull requests

7 participants