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 · 90 comments
Open

TLS 1.3 Cipher Strength 90%? #636

shoujii opened this issue Jul 10, 2018 · 90 comments

Comments

@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
Copy link
Contributor

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

@ArchangeGabriel
Copy link

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
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
Copy link

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

@ArchangeGabriel
Copy link

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
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
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
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
Copy link

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
Copy link

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

@shoujii
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
Copy link

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
Copy link

Fudoshiki commented Jul 21, 2018

@joramk
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
Copy link

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
Copy link

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
Copy link
Author

shoujii commented Nov 19, 2018

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

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

@savely-krasovsky
Copy link

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

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

@savely-krasovsky
Copy link

@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
Copy link

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
Copy link

@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
Copy link

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
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
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
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
Copy link

GreenReaper commented Jan 22, 2019 via email

@ckaspers
Copy link

ckaspers commented May 19, 2020

@wibimaster

No matter what I do, the server keeps forcing the mandatory TLS_AES_128_GCM_SHA256 cipher.
I even tried fully copying your configuration and rebooting the server, it still stays enabled.

To be honest, SSL Labs should just change their system to give us 100% with this cipher enabled.

@axieum
Copy link

axieum commented May 19, 2020

Just tried this, I edited both openssl.cnf and openssl.cnf.dist, to no avail. Using OpenSSL 1.1.1g.

@melroy89
Copy link

Just tried this, I edited both openssl.cnf and openssl.cnf.dist, to no avail. Using OpenSSL 1.1.1g.

Depending on the distribution the files could be located somewhere else like in my case /usr/lib/ssl. Assuming the solution proposed by wibimaster works.

@wibimaster
Copy link

wibimaster commented May 20, 2020

You can use openssl version -a | grep OPENSSLDIR to determinate which file you have to patch.
In my case, output is /usr/lib/ssl, and a simple ls -l on this folder shows that openssl.cnf is a symlink to /etc/ssl/openssl.cnf.

@ckaspers Did you patch at the start of the file and not the bottom ?

Here is a default openssl.cnf, without comments, and with the patch you can see :
https://pastebin.com/ELCwTHB2

Of course my certificate was 4096 bits and dhparam too, to get full 100%.

I didn't reboot my server, only restarted nginx

@melroy89
Copy link

Of course my certificate was 4096 bits and dhparam too, to get full 100%.

You triggered me here. I think you creating self-signed certificate using openssl, is that right? While others may use Let's encrypt as CA ;). Even then, you can create 4096 bits certificates via Let's Encrypt. I do it already. Change your /etc/letsencrypt/cli.ini file, like so:

image

@wibimaster
Copy link

Of course my certificate was 4096 bits and dhparam too, to get full 100%.

You triggered me here. I think you creating self-signed certificate using openssl, is that right? While others may use Let's encrypt as CA ;). Even then, you can create 4096 bits certificates via Let's Encrypt. I do it already. Change your /etc/letsencrypt/cli.ini file, like so:

image

Oh no, I'm using Letsencrypt too ;)
But for TLSv1.3, nginx use openssl to determinate cipher suites ; just patch openssl configuration file and it rocks, nginx follow it :)

@wibimaster
Copy link

Maybe you can check your openssl configuration after editing it :
openssl ciphers -s -v | grep 1.3

It should output :

TLS_AES_256_GCM_SHA384  TLSv1.3 Kx=any      Au=any  Enc=AESGCM(256) Mac=AEAD
TLS_CHACHA20_POLY1305_SHA256 TLSv1.3 Kx=any      Au=any  Enc=CHACHA20/POLY1305(256) Mac=AEAD

Be aware that this modification is system wide. If you want to edit this configuration only for nginx, you have to create another openssl configuration file and modify nginx service to use it (environement variable)

@ckaspers
Copy link

@wibimaster

I checked and my path is also /usr/lib/ssl/openssl.cnf which is a symlink to /etc/ssl/openssl.cnf.
I added the exact same block of text in the exact same place as your file and restarted nginx.

If it makes any difference at all I am running Ubuntu 20.04 LTS on a Raspberry Pi 4B 4GB.
And I'm running OpenSSL version 1.1.1g which is from the 21st of april 2020.

root@raspberrypi:/usr/lib/ssl# ls -l
total 4
lrwxrwxrwx 1 root root   14 Aug 20  2019 certs -> /etc/ssl/certs
drwxr-xr-x 2 root root 4096 May  9 22:55 misc
lrwxrwxrwx 1 root root   20 Apr 21 16:31 openssl.cnf -> /etc/ssl/openssl.cnf
lrwxrwxrwx 1 root root   16 Aug 20  2019 private -> /etc/ssl/private

root@raspberrypi:/usr/lib/ssl# openssl ciphers -s -v | grep 1.3
TLS_AES_256_GCM_SHA384  TLSv1.3 Kx=any      Au=any  Enc=AESGCM(256) Mac=AEAD
TLS_CHACHA20_POLY1305_SHA256 TLSv1.3 Kx=any      Au=any  Enc=CHACHA20/POLY1305(256) Mac=AEAD
TLS_AES_128_GCM_SHA256  TLSv1.3 Kx=any      Au=any  Enc=AESGCM(128) Mac=AEAD

Here's my openssl.cnf file: https://pastebin.com/w5Bxpnsp.

And this is my ssl.conf file in /etc/nginx:

ssl_certificate /etc/letsencrypt/rsa-certs/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/rsa-certs/privkey.pem;
ssl_certificate /etc/letsencrypt/ecc-certs/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/ecc-certs/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/ecc-certs/chain.pem;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_protocols TLSv1.3 TLSv1.2;
ssl_ciphers 'TLS-CHACHA20-POLY1305-SHA256:TLS-AES-256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384';
ssl_ecdh_curve secp521r1:secp384r1;
ssl_prefer_server_ciphers on;
ssl_stapling on;
ssl_stapling_verify on;

It just keeps forcing the "mandatory" 128 bit cipher for whatever reason...

@mddvul22
Copy link

Respectfully, the last two days of comments seem unrelated to the bug report about Qualys' handing of TLS 1.3 scoring. We all want this solved. But it doesn't seem to me that this bug report is the place to figure out a workaround, that doesn't involve Qualys actually fixing the problem.

@wibimaster
Copy link

wibimaster commented May 20, 2020

@ckaspers you missed a thing into openssl configuration, read carefully my comment :

openssl_conf = default_conf

@mddvul22
Sure, but if Qualys think that 128 is insecure for TLSv1.3 too, we have to find a workaround :/

@shoujii
Copy link
Author

shoujii commented May 20, 2020

It’s really funny, I opened this issue nearly 2 years ago and it still persists.

I’m really sad that there is no solution without less or more dirty workarounds:/

@axieum
Copy link

axieum commented May 21, 2020

I'm really sad that there is no solution

@shoujii It is quite disappointing, isn't it.

I have several times to implement @wibimaster's solution, perhaps you could upgrade your OpenSSL to the latest 1.1.1g (over h), and see if your workaround remains?

The only difference I can see between our configurations is the:

[ CA_default ]
dir = /etc/ssl

@ckaspers
Copy link

@wibimaster hmm, I swear I had that in there last time I tested though.
I get the correct ciphers now with openssl ciphers -s -v | grep 1.3.

I don't know what changed, but everything is working correctly and I have 100% now.

@wibimaster
Copy link

wibimaster commented May 22, 2020

@wibimaster hmm, I swear I had that in there last time I tested though.
I get the correct ciphers now with openssl ciphers -s -v | grep 1.3.

I don't know what changed, but everything is working correctly and I have 100% now.

Glad to see that it works for you :)

About all this thread :
I'm ABSOLUTELY NOT a security expert. Before TLSv1.3 story, nobody says "what, we have to change nginx configuration file to have 100 % ? Dirty hack !"

If Qualys says "Having a 128 bit in ciphers list is not secure", I follow them.
If it's not quite as easy as just update nginx.conf, it's not Qualys fault ; it's openssl that closes the possibility to update this ciphers list from external tools (if I understood correctly).

But you can update this configuration, you can have a specific openssl configuration file for nginx if you don't want to have this patch system-wide, and you don't have to build anything.
If it's related to newer openssl or nginx version that the ones you have, just update them ; someone really concerned with security tries to stay up to date :)

For this specific thread, you can have 100% with TLSv1.3 quite easily.

Maybe another thread with "TLSv1.3 with 128 bits in ciphers list should be considered secured" could be opened, but I'm not an expert.
Maybe an issue could be opened between openssl and nginx to override standard configuration RFC compliant like for TLSv1.2, but it's not into Qualys spectrum :)

@axieum
Copy link

axieum commented May 22, 2020

Managed to get it working by purging my OpenSSL

Arch Linux 5.6.13.a-1-hardened x86_64
OpenSSL 1.1.1g 21 Apr 2020

rm -rf /etc/ssl/*
pacman -S openssl

..creating a /etc/ssl/cipherquites.cnf file - for organisation

# Ciphersuites Configuration

MinProtocol             = TLSv1.2
CipherString            = DEFAULT@SECLEVEL=2
Ciphersuites            = TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
Options                 = ServerPreference,PrioritizeChaCha

..inserting the following lines into /etc/ssl/openssl.cnf

@@ -11,6 +11,17 @@
# defined.
HOME                   = .

+openssl_conf           = default_conf
+
+[ default_conf ]
+ssl_conf               = ssl_section
+
+[ ssl_section ]
+system_default         = ssl_sys_section
+
+[ ssl_sys_section ]
+.include               /etc/ssl/ciphersuites.cnf
+
# Extra OBJECT IDENTIFIER info:
#oid_file              = $ENV::HOME/.oid
oid_section            = new_oids

..and finally restarting Nginx (a reload didn't seem to work for me).

systemctl restart nginx

If it doesn't immediately work, try do a reboot.

Results

image
image

Nginx TLS configurations

/etc/nginx/tls.conf:

ssl_session_cache               shared:SSL:10m;
ssl_session_timeout             10m;
ssl_session_tickets             off;

ssl_protocols                   TLSv1.3 TLSv1.2;
ssl_prefer_server_ciphers       on;
ssl_ecdh_curve                  secp521r1:secp384r1;
ssl_ciphers                     "ECDHE+ECDSA+CHACHA20:ECDHE+ECDSA+AESGCM:!AES128";

ssl_stapling                    on;
ssl_stapling_verify             on;

resolver                        1.1.1.1 1.0.0.1 valid=300s;
resolver_timeout                5s;

add_header                      Expect-CT "enforce; max-age=2592000; report-uri=\"https://tls.example.net\"" always;
add_header                      Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

Thanks @wibimaster and @ckaspers! 🎉

@ertuzio
Copy link

ertuzio commented May 24, 2020

Sorry but this doesn't give all 100%

can you reupload your screen-shot with date?

@wibimaster
Copy link

Sorry but this doesn't give all 100%

can you reupload your screen-shot with date?

Which one ? Mine or Axieum's ?

@ertuzio
Copy link

ertuzio commented May 24, 2020

Axieum's
Now I tried your ciphers @wibimaster and it works.... all 100% and A+

ALL:!AES128:!CAMELLIA128:!CAMELLIA:!ARIA128:!RSA:!SEED:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK:!DHE-RSA-AES256:!ECDHE-RSA-AES256-SHA384:!DHE-RSA-AES256-SHA256:!ECDHE-RSA-AES256-SHA:!DHE-RSA-AES256-SHA:@strength

with updated etc/ssl/openssl.cnf

@abradshaw
Copy link

@wibimaster comment from 18th May did the trick for me, on CentOS8 - just needed to alter 1 line in the openssl config

Here is the part of my ansible playbook that takes care of this

- name: Ensure older ciphers cant be used by openssl
  lineinfile:
    path: /etc/crypto-policies/back-ends/opensslcnf.config
    regexp: '^Ciphersuites'
    line: 'Ciphersuites = TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256'

@mddvul22
Copy link

TLS_AES_128_GCM_SHA256 is a required cipher for TLS 1.3. RFC 8446 mandates it. In fact, there is a considerable argument to be made that AES 128 is actually more secure than something using AES 256. (Link) Openssl's default configuration is correct here. The correct fix, in the end, is for Qualys to correct their scoring. You guys are arguably weakening your security by removing TLS_AES_128_GCM_SHA256 -- just so that you can get 100%.

@TCHessen
Copy link

You're right that TLS_AES_128_GCM_SHA256 is a mandated cipher for a TLS 1.3 implementation, but no one says my server has to provide it. Suppose an RFC for 1.3 requires a CIPHER with DES and 256 RSA, would you provide it? But I agree that an AES128 should not lower the rating to 90% because it is not actually insecure, but don't argue with an RFC that doesn't guarantee any security.

@ygoe
Copy link

ygoe commented Dec 11, 2020

Folks, just scan a Google website (the only one I could find that uses ECDSA certificates instead of RSA) and look at their results. It's a plain B. That's not even green anymore. So I, for one, am quite happy to get an A with some 90% scores. I don't see the difference between 128 and 256 bit encryption, which translates roughly to "practically unbreakable" and "practically unbreakable".

@beatquantum
Copy link

I just wish to confirm that the solution from wibimaster works on openssl 1.1.1i and nginx 1.19.6.
Fyi - I used secp384r1
Thank you!

@SagePtr
Copy link

SagePtr commented Aug 11, 2021

Note: starting from nginx 1.19.4 and later you can specify TLSv1.3 cipher suites right in the nginx config:

ssl_conf_command Ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256;

I used this to achieve 100/100/100/100 (in conjunction with EC P-384 certificate signed by E1 Let's Encrypt intermediate):

ssl_protocols     TLSv1.2 TLSv1.3;
ssl_ciphers       ECDH+AESGCM+AES256:ECDH+CHACHA20; # TLSv1.2
ssl_conf_command  Ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256; # TLSv1.3
ssl_ecdh_curve    secp384r1;

It screws some old clients, and p384 is much slower than p256 (on my VPS it's even twice slower than rsa2048), so it's better not to use this in production, unless you are extremely paranoid about the possibility of cracking AES-128 and/or EC P-256.

@beatquantum
Copy link

Huge thanks @SagePtr - Good to know nginx can specify the ciphers directly; so we do not need to play with openssl.cnf.

I liked your comments that helped to research further. The "old clients" are actually include Chrome 49 (for Win XP), Firefox 31 (for Win 7), Safari 8 (for Yosemite) and older versions and it makes no sense to use them in August 2021. So the issue of incompatibility is effectively for visitors using Android 6 or older; which in 2021 is less than 5% of the total Android population anyway and no longer receive security updates. So each one has to take a business decision for themselves, whether to provide backward compatibility with obsolete browsers and operating systems.

As my servers CPU usage is very low and the pagespeed result is acceptable (with p384); there was no need to use p256.

I find it is difficult to distinguish between extreme paranoids, score junkies and good cyber practices. Their venn diagrams overlap!

@HepplerDotNet
Copy link

@SagePtr thanks, with this config I get 100/100/100/100.
But this also disables 0-RTT. Any idea which ECDH curve can be used to stay on 100 Key Exchange and enable 0-RTT?
Commenting out ssl_ecdh_curve enables 0-RTT, but cuts Key Echange down to 90

@SagePtr
Copy link

SagePtr commented Aug 16, 2021

@SagePtr thanks, with this config I get 100/100/100/100.
But this also disables 0-RTT. Any idea which ECDH curve can be used to stay on 100 Key Exchange and enable 0-RTT?
Commenting out ssl_ecdh_curve enables 0-RTT, but cuts Key Echange down to 90

Tested with openssl s_client and figured it out: when i specify -curve secp384r1 parameter in the client, the 0-RTT data is accepted, but when i don't specify any curve list, the 0-RTT data is rejected. If i specify X25519 among ssl_ecdh_curve list (on the server) - 0-RTT works anyway, but drops kex score to 90. Ideally, 0-RTT should not be used in a strong crypto setup, as it slightly reduces the security of the first packet for the sake of a faster handshake.
UPD:
I tested on real browsers (Firefox and Chrome). During the handshake, Firefox sends two key share entries: computed with x25519 and prime256v1. Chrome sends two key shares as well, but one is GREASE, the second is x25519. They don't memoize what curve was used during the last handshake. So, in both browsers, if the server doesn't allow x25519, it replies with "Hello Retry Request" screwing up 0-RTT and 1-RTT speed as well. That's the another reason why removing x25519 from the curve list makes TLS session establishment slight slower (besides the lack of secp384r1 low-level optimizations in OpenSSL).

@HepplerDotNet
Copy link

@SagePtr thanks!
My setup doesn't really require high security. So I stick with:
ssl_ecdh_curve X25519:secp521r1:secp384r1;
That way 0-RTT works and a Key Ex 90 is still fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests