ssllabs / ssllabs-scan

A command-line reference-implementation client for SSL Labs APIs, designed for automated and/or bulk testing.
https://www.ssllabs.com/projects/ssllabs-apis/
Apache License 2.0
1.69k stars 239 forks source link

TLS 1.3 Cipher Strength 90%? #636

Open shoujii opened 6 years ago

shoujii commented 6 years ago

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 commented 6 years ago

Cipher strength is calculated as per this guide https://github.com/ssllabs/research/wiki/SSL-Server-Rating-Guide#cipher-strength

ArchangeGabriel commented 6 years ago

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 commented 6 years ago

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 commented 6 years ago

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

ArchangeGabriel commented 6 years ago

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 commented 6 years ago

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 commented 6 years ago

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 commented 6 years ago

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 commented 6 years ago

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 commented 6 years ago

(And the PR that changed this https://github.com/openssl/openssl/pull/5392)

shoujii commented 6 years ago

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 commented 6 years ago

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 commented 6 years ago

https://trac.nginx.org/nginx/ticket/1529 https://trac.nginx.org/nginx/ticket/1533

joramk commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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

realasmo commented 5 years ago

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

savely-krasovsky commented 5 years ago

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

iz8mbw commented 5 years ago

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.

savely-krasovsky commented 5 years ago

@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 commented 5 years ago

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.

savely-krasovsky commented 5 years ago

@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 commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

At a guess, the version of OpenSSL you compiled will be using the --prefix configure argument to specify where it stores its own configuration files.

Of course you could also change its compiled-in order. Personally I would tend towards using fewer patches if a config can achieve the same goal.


From: Fabio notifications@github.com Sent: Tuesday, January 22, 2019 1:53:48 PM To: ssllabs/ssllabs-scan Cc: GreenReaper; Mention Subject: Re: [ssllabs/ssllabs-scan] TLS 1.3 Cipher Strength 90%? (#636)

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.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://github.com/ssllabs/ssllabs-scan/issues/636#issuecomment-456406753, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AAXYQ_RpXb0OsKDBuO9mw-QUkBhl0d-yks5vFxfsgaJpZM4VJY_W.

iz8mbw commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

@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 commented 5 years ago

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 commented 5 years ago

@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 commented 5 years ago

@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 commented 5 years ago

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 commented 5 years ago

@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 commented 5 years ago

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-0 commented 5 years ago

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 commented 5 years ago

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

Dual-0 commented 5 years ago

@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 commented 5 years ago

Not AFAIK.

jsuelwald commented 5 years ago

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 commented 5 years ago

IMHO, TLS_AES_128_GCM_SHA256 for TLSv1.3 should give 100%

tamthing commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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

GreenReaper commented 5 years ago

Because it's about 30% faster, but still secure? As I noted this is the case with or without hardware, because it relates to the number of iterations of the functions as well as the size of the operands.

Indeed, issues have been found in 256-bit (and 192-bit) AES that are not in 128-bit AES, leading some to suggest that 128-bit is the most secure: https://www.schneier.com/blog/archives/2009/07/another_new_aes.html

This does not yet have (many?) practical implications, but if more and more serious deficiencies are found, it'd be beneficial to have a similar, as-yet-secure algorithm with hardware acceleration.

Similarly, if 128-bit is ultimately found to be deficient, you can switch algorithms at that point, and meanwhile reap the performance benefit.

Mikotochan commented 5 years ago

@GreenReaper I think that batch attacks are a bigger issue compared to a related-key attack which only affects a reduced-version of AES256. See https://blog.cr.yp.to/20151120-batchattacks.html The real question is why AES is included at all when we have Chacha20.