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

TLS 1.3 Cipher Strength 90%? #636

Open
shoujii opened this Issue Jul 10, 2018 · 49 comments

Comments

Projects
None yet
@shoujii
Copy link

shoujii commented Jul 10, 2018

Hey there,
I tested my site -> nginx 1.15.1 using Openssl 1.1.1 pre release 8 on

https://dev.ssllabs.com/

with the following cipher list:
TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-256-GCM-SHA384:TLS13-AES-128-GCM-SHA256

and I only got 90% Cipher Strength.

Am I doing something wrong?

https://www.openssl.org/blog/blog/2017/05/04/tlsv1.3/

There are only 5 TLS 1.3 Ciphers supported by openssl yet.

@bhushan5640

This comment has been minimized.

Copy link
Collaborator

bhushan5640 commented Jul 11, 2018

@ArchangeGabriel

This comment has been minimized.

Copy link

ArchangeGabriel commented Jul 11, 2018

You have to remove TLS13-AES-128-GCM-SHA256 from your cipher list if you want to score 100 %, because SSL Labs scores any <256 bits cipher with a score lower than 100 %.

@shoujii

This comment has been minimized.

Copy link
Author

shoujii commented Jul 11, 2018

Ah I got the mistake...

The SSL Labs test isn't refreshing the ciphers / making the test again, so the 128 Bit cipher doesn't disappear.
I reactivated the Server Snapshot and tried to scan again... same result 90%
After deleting the 128 bit cipher, I ran the test again, but it's showing the old result from 2 hours ago.

https://dev.ssllabs.com/ssltest/analyze.html?d=next-server.eu&s=46.251.251.145&hideResults=on&latest

Is that behaviour normal?

So: TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-256-GCM-SHA384 are the only 2 TLS 1.3 ciphers that can get 100%?

@ArchangeGabriel

This comment has been minimized.

Copy link

ArchangeGabriel commented Jul 11, 2018

Clearing the cache this results in the same, did you restart your nginx server after removing the cipher?

@ArchangeGabriel

This comment has been minimized.

Copy link

ArchangeGabriel commented Jul 11, 2018

Oh, one thing I’ve just remembered is that it seems to me OpenSSL splitted specifying TLS 1.3 ciphers from previous version, so that nginx cannot currently set TLS 1.3 ciphers.

@shoujii

This comment has been minimized.

Copy link
Author

shoujii commented Jul 11, 2018

did you restart your nginx server after removing the cipher?

Sure :P
https://i.imgur.com/2F29OIs.jpg
And forget that time thing, it's UTC, so ssl labs is refreshing (I guess) :D

Oh, one thing I’ve just remembered is that it seems to me OpenSSL splitted specifying TLS 1.3 ciphers from previous version, so that nginx cannot currently set TLS 1.3 ciphers.

How do you mean that?
That Openssl is setting this 3 ciphers as default and nginx isn't able to influence that?

https://www.openssl.org/blog/blog/2017/05/04/tlsv1.3/

Of these the first three are in the DEFAULT ciphersuite group. This means that if you have no explicit ciphersuite configuration then you will automatically use those three and will be able to negotiate TLSv1.3.
(This includes the 128 bit cipher)

But in my setting they are set :O

@ArchangeGabriel

This comment has been minimized.

Copy link

ArchangeGabriel commented Jul 11, 2018

That Openssl is setting this 3 ciphers as default and nginx isn't able to influence that?

Yes, exactly. nginx lacks the code to handle that AFAIK.

@shoujii

This comment has been minimized.

Copy link
Author

shoujii commented Jul 11, 2018

Wow okay, that's totally new to me.

Have you experienced the same, or heard of someone who has the same issue / read somewhere that the code is missing?
But I understand it, we're messing around with a really new feature (even Openssl 1.1.1 is a Beta too)

@ArchangeGabriel

This comment has been minimized.

Copy link

ArchangeGabriel commented Jul 11, 2018

I’ve read this in OpenSSL changelog:

  *) Added a new API for TLSv1.3 ciphersuites:
        SSL_CTX_set_ciphersuites()
        SSL_set_ciphersuites()
     [Matt Caswell]

And a bit further down the notes:

  *) Separated TLSv1.3 ciphersuite configuration out from TLSv1.2 ciphersuite
     configuration. TLSv1.3 ciphersuites are not compatible with TLSv1.2 and
     below. Similarly TLSv1.2 ciphersuites are not compatible with TLSv1.3.
     In order to avoid issues where legacy TLSv1.2 ciphersuite configuration
     would otherwise inadvertently disable all TLSv1.3 ciphersuites the
     configuration has been separated out. See the ciphers man page or the
     SSL_CTX_set_ciphersuites() man page for more information.
     [Matt Caswell]

I don’t know of any project that has updated its code to use this new API.

@ArchangeGabriel

This comment has been minimized.

Copy link

ArchangeGabriel commented Jul 11, 2018

(And the PR that changed this openssl/openssl#5392)

@shoujii

This comment has been minimized.

Copy link
Author

shoujii commented Jul 11, 2018

Ahh thanks for your research!

On Openssl side:
SSL_CTX_set_cipher_list is for TLS 1.2 (and below)
SSL_CTX_set_ciphersuites is for TLS 1.3
if I am right?

So adding / changing the new API for TLS1.3 here:
https://github.com/nginx/nginx/blob/f62d460d5bb4b89c7932b4193023bee7f522249a/src/event/ngx_event_openssl.c#L632

would probably fix it (there are maybe more files to change I guess).
I'm not a programmer, so be kind if I'm wrong ;D

@ArchangeGabriel

This comment has been minimized.

Copy link

ArchangeGabriel commented Jul 11, 2018

Yeah, they are more changes required depending on how they want to support this. If you want to do a dirty try with only TLS 1.3 support, you could swap the new API in place of the TLS 1.2 one in nginx and see what it gives.

@Fudoshiki

This comment has been minimized.

@joramk

This comment has been minimized.

Copy link

joramk commented Aug 5, 2018

You should not remove this cipher. draft-ietf-tls-tls13-28 RFC says:

9.1. Mandatory-to-Implement Cipher Suites

In the absence of an application profile standard specifying otherwise, a TLS-compliant application MUST implement the TLS_AES_128_GCM_SHA256 cipher suite and SHOULD implement the TLS_AES_256_GCM_SHA384 and TLS_CHACHA20_POLY1305_SHA256 cipher suites.
A TLS-compliant application MUST support digital signatures with rsa_pkcs1_sha256 (for certificates), rsa_pss_rsae_sha256 (for CertificateVerify and certificates), and ecdsa_secp256r1_sha256. A TLS-compliant application MUST support key exchange with secp256r1 (NIST P-256) and SHOULD support key exchange with X25519.

IMHO SSLlabs should change the scoring. When there is a better cipher available and ordered before the mandatory AES128 ciphers for HTTP/2 with TLS 1.2 or TLS 1.3 it should be 100% not 90% for "Cipher Strength".

Also supporting secp256r1 is mandatory for TLS 1.3 and reduces the score for "Key Exchange" by 10%. Even when there is secp384r1 available and preferred by the server. This also should give 100% and not 90% for "Key Exchange".

@ArchangeGabriel

This comment has been minimized.

Copy link

ArchangeGabriel commented Aug 6, 2018

Or decide to not be standard compliant. I don’t trust NIST ECC, so no secp256r1 on my servers.

And I’m not sure whether the scoring should be changed: you are less secure than someone without 128-bits equivalent crypto. However, maybe a warning should be issued regarding standard compliance if you reach 100%, and when you are at 90% have some info printed alongside it saying that 100% cannot be reached within RFC compliance.

@myfirstnameispaul

This comment has been minimized.

Copy link

myfirstnameispaul commented Nov 19, 2018

The notion that a better available cipher is a solution seems to be not understanding attack vectors - the server will "prefer" the highest cipher the client can support. Attackers simply use clients that declare they do not have the highest ciphers, and the fun begins.

From a broader perspective, the security in open source depends on projects such as this one to independently confirm other projects as secure. If the IETF publishes 8-bit ciphers into a standard, OpenSSL adds 8-bit ciphers to their default configuration and requires its use, does that mean SSL Labs should declare 100%, except for when 8-bit ciphers are used? No! It means the server gets 0% and F.

This concept applies to 128-bit as well; if SSL Labs determines 128-bit gets 80%, then this is the case no matter what IETF or OpenSSL publish.

@shoujii

This comment has been minimized.

Copy link
Author

shoujii commented Nov 19, 2018

Has someone tested that?
https://trac.nginx.org/nginx/ticket/1529

@realasmo

This comment has been minimized.

Copy link

realasmo commented Nov 26, 2018

Has someone tested that?
https://trac.nginx.org/nginx/ticket/1529

I've tested the equivalent option in Apache 2.4.37

for TLSv1.2:
SSLCipherSuite CIPHER1:CIPHER2 ..
for TLSv1.3:
SSLCipherSuite TLSv1.3 CIPHER1:CIPHER2 ..

With just the TLS_AES_256_GCM_SHA384 & TLS_CHACHA20_POLY1305_SHA256 TLS1.3 ciphers and without the secp256r1 I got 100% key exchange score.

https://www.ssllabs.com/ssltest/analyze.html?d=3ov6.ml&s=2a01%3a4f8%3a221%3a3f8a%3a0%3a0%3a0%3a2&latest

@L11R

This comment has been minimized.

Copy link

L11R commented Dec 6, 2018

@shoujii I tried, it changes output of openssl ciphers tool, but SSLLabs still gives me same result (90% because of AES128).

@iz8mbw

This comment has been minimized.

Copy link

iz8mbw commented Dec 10, 2018

Someone have understood how to have this TLS 1.3 ciphers order with nginx and OpenSSL:

TLS_AES_128_GCM_SHA256
TLS_AES_256_GCM_SHA384
TLS_CHACHA20_POLY1305_SHA256

?
Thanks.

@L11R

This comment has been minimized.

Copy link

L11R commented Dec 11, 2018

@iz8mbw it's impossible right now. Nginx cannot use new OpenSSL API for TLS v1.3 yet.

P.S. Why you need this order? Many processors support AES-NI, so proceed 256 as fast as 128.

@GreenReaper

This comment has been minimized.

Copy link

GreenReaper commented Dec 29, 2018

That does not appear to be the case, if I'm benchmarking correctly. openssl speed -evp aes-256-cbc is consistently ~30% slower than aes-128-cbc (or to put it the other way around, 128 is 40% faster than 256).

AES-NI makes things five to six times faster - evp without it has a speedup, too - but the difference between 128 and 256 remains proportional. They may equally be 'fast enough', but it depends on your requirements.

@L11R

This comment has been minimized.

Copy link

L11R commented Dec 29, 2018

@GreenReaper my point: Site content affects speed MUCH more than AES choice. So I will just choose more secure AES256. For mobile devices there is also ChaCha20-Poly1305 that is also doesn't require AES-NI and still performs well enough in both cases: speed and security.

@ArchangeGabriel

This comment has been minimized.

Copy link

ArchangeGabriel commented Jan 14, 2019

So in a nutshell we are forced to have the 128 bit cipher as per https://wiki.openssl.org/index.php/TLS1.3#Ciphersuites but the Qualys punishes us for having this. So does the test have to be updated? As in having 128 bit ciphers is less secure but should not be punished.

Or the OpenSSL people have to decide to drop the TLS_AES_128_GCM_SHA256 cipher requirement.

Or am I completely wrong and I have no idea wtf I'm talking about. I for one will not willingly run with <256bit ciphers.

I’m replying here to this now deleted message: the standard might have requirements that are not compatible with security, yes. For instance, until recently the mandatory cipher in previous versions of TLS was a 3DES one… Or even currently, you have to support NIST elliptic curves. So yes, if you want highest security, you cannot be standard-compliant.

@iz8mbw

This comment has been minimized.

Copy link

iz8mbw commented Jan 22, 2019

Hi all.
The solution to have a different TLSv1.3 Ciphers order with OpenSSL 1.1.1a and nginx (and I think also other web server since the modification will be in OpenSSL) is to change the Ciphers order into the file "ssl.h" located in OpenSSL source code (openssl_source_dir/include/openssl).
Here there is the patch file: https://gist.github.com/kteru/667292b9c1d3c68604c15f7def738e71
So you need to first download "OpenSSL 1.1.1a" source code, then patch the file "ssl.h", and then compile it again.

@GreenReaper

This comment has been minimized.

Copy link

GreenReaper commented Jan 22, 2019

That should not be required if you are willing to change cipher order preferences globally. Just set up a Ciphersuites entry in /etc/ssl/openssl.conf (I suggest also using the listed Options for the benefit of mobile devices).

@iz8mbw

This comment has been minimized.

Copy link

iz8mbw commented Jan 22, 2019

Ok.
But I did not understand how manage "openssl.cnf"...
On my Linux system I have two OpenSSL, one is the default of my Linux distro (1.0.1t) and the other is OpenSSL 1.1.1a built by myself and located in "/opt/ssl".
Nginx (also built by me from source code) is "linked" to the OpenSSL 1.1.1a.
Well, now, to properly set the TLSv1.3 Ciphers order using "openssl.cnf", what and how should I do that?
Thanks.

@GreenReaper

This comment has been minimized.

Copy link

GreenReaper commented Jan 22, 2019

@iz8mbw

This comment has been minimized.

Copy link

iz8mbw commented Jan 22, 2019

Ok, in my case the OpenSSL 1.1.1a conf file is on "/opt/ssl/openssl.cnf".
If I go to edit that file with "Ciphersuites entry" as you suggested, how nginx will go to use that new Ciphers order?

This is what I did not understand...

@GreenReaper

This comment has been minimized.

Copy link

GreenReaper commented Jan 23, 2019

Because nginx instructs OpenSSL to load its default config as part of its startup routine.

Bear in mind that the bit I linked earlier is an bit of additional setting based on a distro which actually sets up a default config. If you don't have that (like if you're upgrading from a distro which doesn't) you need some more comprehensive additions to the default config, like this:

# System default - outside any settings group
openssl_conf = default_conf
....
[default_conf]
ssl_conf = ssl_sect

[ssl_sect]
system_default = system_default_sect

[system_default_sect]
Ciphersuites = TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_128_CCM_8_SHA256
Options = ServerPreference,PrioritizeChaCha

There may be a good way to make it work just for nginx but I figure that if you want the above settings, you probably want them as the default anyway. Note that other nginx settings continue to take effect, this just lets you ensure that a) TLS 1.3 cyphersuites are ordered as you wish (putting them in nginx's ssl_ciphers list doesn't do this) and b) ChaCha is prioritized where the client prefers it to the extent of putting it first.

@iz8mbw

This comment has been minimized.

Copy link

iz8mbw commented Jan 23, 2019

I have tried to add

# System default - outside any settings group
openssl_conf = default_conf
....
[default_conf]
ssl_conf = ssl_sect

[ssl_sect]
system_default = system_default_sect

[system_default_sect]
Ciphersuites = TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_128_CCM_8_SHA256
Options = ServerPreference,PrioritizeChaCha

(note the first is "TLS_AES_256_GCM_SHA384" because I already patched my "ssl.h" fot the TLS 1.3 cyphersuites order having "TLS_AES_128_GCM_SHA256" as primary) to my "/opt/ssl/openssl.cnf" just for test, then I restarted nginx but TLS 1.3 cyphersuites order did not change respect to the order already in place on the patched "ssl.h"

@naumanshah03

This comment has been minimized.

Copy link
Contributor

naumanshah03 commented Jan 24, 2019

@realasmo thanks for sharing that domain name
SSL Labs now detects TLS 1.3 mandatory cipher implementation compliance from version 1.32.15

https://www.ssllabs.com/ssltest/analyze.html?d=3ov6.ml

@HepplerDotNet

This comment has been minimized.

Copy link

HepplerDotNet commented Jan 29, 2019

I'm running nginx on Centos 7. I downloaded openssl-1.1.1 to /opt, applied the ssl.h patch and recompiled nginx. Still 90%. Next I tried to remove AES128 from ssl.h and got 100% but with a warning that my server doesn't support AES128.

@iz8mbw

This comment has been minimized.

Copy link

iz8mbw commented Jan 30, 2019

@HepplerDotNet I did not get your point... may be you are confusing 100% score and 90% score with the scope of patching "ssl.h".... Patching "ssl.h" is ONLY to change the TLS1.3 cipher order with nginx. For TLS1.3 all the cipher order combination should be OK for SSL Lab Server test.

@HepplerDotNet

This comment has been minimized.

Copy link

HepplerDotNet commented Jan 30, 2019

@iz8mbw
Before I activated TLS1.3, I always got a 100/100/100/100. After activating TLS1.3 I only get 100/100/100/90. So I searched Google and found some posts, that nginx can't handle the cipher order for TLS1.3

So I tried the ssl.h patch, but still 90% cipher strength. If I remove TLS_AES_128_GCM_SHA256 from ssl.h I get 100% cipher strength, but with a warning for not supporting TLS_AES_128_GCM_SHA256

This is the ssl part of my nginx.conf:

ssl on;
ssl_stapling on;
ssl_stapling_verify on;
ssl_protocols   TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_early_data on;
ssl_ciphers 'TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-256-GCM-SHA384:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:!AES128';
ssl_session_cache shared:SSL:20m;
ssl_session_timeout 24h;
ssl_buffer_size 1400;
ssl_session_tickets off;
ssl_ecdh_curve secp384r1;
add_header Strict-Transport-Security "max-age=31536000;includeSubDomains;preload";
@ArchangeGabriel

This comment has been minimized.

Copy link

ArchangeGabriel commented Jan 30, 2019

You need to remove all AES128 ciphers to get 100%. But you cannot remove TLS 1.3 ciphers from nginx, and the only way to do so is to compile without support for it AFAIK.

So your nginx ciphers string is equivalent to EECDH+CHACHA20:EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:!AES128. BTW, would I be you, I would remove those AES256+EECDH:AES256+EDH that includes CBC modes for AES, and replace them with EECDH+AESCCM:EDH+AESCCM, which are the only relevant modes from the above strings. And finally I would remove EDH modes altogether, since some of them (DSA a.k.a. DHE-DSS ones) are removed in TLS 1.3, and you already did not include e.g. EDH+CHACHA20.

Thus, I would just have: EECDH+CHACHA20:EECDH+AESGCM:EECDH+AESCCM:!AES128.

@HepplerDotNet

This comment has been minimized.

Copy link

HepplerDotNet commented Jan 31, 2019

@ArchangeGabriel
that's paradox!
With TLS_AES_128_GCM_SHA256 I get 90%, without TLS_AES_128_GCM_SHA256 I get 100% but with a warning for not supporting TLS_AES_128_GCM_SHA256

@ArchangeGabriel

This comment has been minimized.

Copy link

ArchangeGabriel commented Jan 31, 2019

Yes, that’s what we have been saying all this thread long: standard compliance requires TLS_AES_128_GCM_SHA256, but 100% requires no AES128 ciphers.

Now it’s up to you to decide whether you want to be standard compliant or more secure. But anyway, there is much more to be done for being more secure than just reaching 100% here, so… For instance, as I said above, there is the case of NIST ECC. I’ve disabled them long ago (ever since Ed25519 landed on both sides). But then, all of this is basically moot if you don’t have something to protect you from the CA Forum and your DNS registrar, and DANE doesn’t really solve things here —just makes them better. You need something like HPKP (but this has been deprecated).

@dual-oo

This comment has been minimized.

Copy link

dual-oo commented Feb 1, 2019

You need to remove all AES128 ciphers to get 100%. But you cannot remove TLS 1.3 ciphers from nginx, and the only way to do so is to compile without support for it AFAIK.

So your nginx ciphers string is equivalent to EECDH+CHACHA20:EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:!AES128. BTW, would I be you, I would remove those AES256+EECDH:AES256+EDH that includes CBC modes for AES, and replace them with EECDH+AESCCM:EDH+AESCCM, which are the only relevant modes from the above strings. And finally I would remove EDH modes altogether, since some of them (DSA a.k.a. DHE-DSS ones) are removed in TLS 1.3, and you already did not include e.g. EDH+CHACHA20.

Thus, I would just have: EECDH+CHACHA20:EECDH+AESGCM:EECDH+AESCCM:!AES128.

When I set EECDH+CHACHA20:EECDH+AESGCM:EECDH+AESCCM:!AES128 ssllabs says 90% cipher and TLS_AES_128_GCM_SHA256 (0x1301) ECDH secp384r1 (eq. 7680 bits RSA) FS.

what do I wrong?

@ArchangeGabriel

This comment has been minimized.

Copy link

ArchangeGabriel commented Feb 1, 2019

@dual-oo The answer is in the first line you quote. You need to recompile OpenSSL without TLS_AES_128_GCM_SHA256.

@dual-oo

This comment has been minimized.

Copy link

dual-oo commented Feb 1, 2019

@dual-oo The answer is in the first line you quote. You need to recompile OpenSSL without TLS_AES_128_GCM_SHA256.

is there a way with an other config and without recompiling?

@ArchangeGabriel

This comment has been minimized.

Copy link

ArchangeGabriel commented Feb 1, 2019

Not AFAIK.

@jsuelwald

This comment has been minimized.

Copy link

jsuelwald commented Feb 7, 2019

Just tested again here:

Either enable "TLS_AES_128_GCM_SHA256" for TLSv1.3 and only get 90%
or
Disable it, get 100%, but also get a warning, that the RFC specified one should enable this Cipher (which confuses me, to be honest)

@iz8mbw

This comment has been minimized.

Copy link

iz8mbw commented Feb 7, 2019

IMHO, TLS_AES_128_GCM_SHA256 for TLSv1.3 should give 100%

@tamthing

This comment has been minimized.

Copy link

tamthing commented Feb 8, 2019

Dear all, we at SSL Labs are working on grading related changes at the moment. This would include changes related to TLS 1.3 protocol. Until then the effect on the score due to TLS_AES_128_GCM_SHA256 cipher suite would continue to exists, along with the alert error message on servers that do not support this mandatory cipher suite as per RFC-8446.

@Verequies

This comment has been minimized.

Copy link

Verequies commented Feb 14, 2019

I'm a bit confused, can you disable the TLS_AES_128_GCM_SHA256 with the openssl.conf? Iif so where about is this configuration file located? I've tried editing /etc/ssl/openssl.cnf but it didn't do anything.

@ArchangeGabriel

This comment has been minimized.

Copy link

ArchangeGabriel commented Feb 14, 2019

I'm a bit confused, can you disable the TLS_AES_128_GCM_SHA256 with the openssl.conf? Iif so where about is this configuration file located? I've tried editing /etc/ssl/openssl.cnf but it didn't do anything.

No, you cannot. You have to recompile OpenSSL to disable this cipher.

@jsuelwald

This comment has been minimized.

Copy link

jsuelwald commented Feb 21, 2019

And, not related to that issue directly, but i wonder why anyone would include AES_128 in TLSv1.3 to begin with..

@GreenReaper

This comment has been minimized.

Copy link

GreenReaper commented Feb 21, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.