Openssl: How to specify to use X25519 with ECC?

Created on 7 Jan 2017  路  4Comments  路  Source: openssl/openssl

My nginx is:

nginx version: nginx/1.11.5
built by gcc 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.1) 
built with OpenSSL 1.1.0c  10 Nov 2016
TLS SNI support enabled
configure arguments: --add-module=../ngx_brotli --add-module=../nginx-ct-1.3.1 --with-openssl=../openssl --with-http_v2_module --with-http_ssl_module --with-http_gzip_static_module --with-cc-opt=-Wno-deprecated-declarations

My openssl is 1.1.0c
My cert is ECC384 from let's encrypt

lines from nginx.conf are below:

# hide the nginx version to make it more safe
server_tokens   off;

# sslv3 is not safe , so not supproted , but not supporting sslv3 may cause the fact that low version browser can not visit this site 
ssl_protocols TLSV1.1 TLSv1.2;
ssl_prefer_server_ciphers on; 

# ssl ciphers 
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;

# this is a param used in ECDHE , by default it is 256
#ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0

# for some reason, using X25519 instead of secp384r1
ssl_ecdh_curve X25519;


resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

I found a strange thing:
if I specify ssl_ecdh_curve X25519; in Nginx conf file , my chrome(55 x64) and firefox will not be albe to visit my site:
image

Howerver, if I comment the line ssl_ecdh_curve X25519;, it will work , and the chrome says it is X25519:
image

but the firefox:
image

A little bit strange why 2 different browser will give different results.

So I want to figure out two questions:

  1. Can I specify x25519 while using ECC384 cert? And how?
  2. If I can not use x25519 with ECC 384 cert , is it a bug of chrome ?

Most helpful comment

My understanding:
ECC cert use a curve and the key exchange procedure also use a curve.
These two can be different.
However, if you set
ssh_ecdh_curve X25519;
into the Nginx under openssl 1.1.0c
the Nginx/openssl will use X25519 to both the two places above .which is not correct because X25519 can only be used in key exchange.

My solution is (only suitable for my config):

  1. Do not set ssh_ecdh_curve , then the nginx will use its default settings, which can reach my goals because chrome will prefer X25519, but this is not recommended because you can not control the nginx's default settings(seems to be P-256).
  2. explicitly set ssh_ecdh_curve X25519:spec384r1; this is perfect for me because chrome and other browsers forked from chrome(I mean use similar kernel will prefer X25519)

All 4 comments

This should really have been a question on the openssl-users mailing list...

This is a known issue in OpenSSL 1.1.0. When you explicitly specify
the list of supported curves (by selecting an explicit ecdhe curve)
this limits the set of curves supported in certificates, and in particular,
the the secp384r1 cert is not matched.

Correct behaviour would be to restrict only ECDHE to X25519, and for
certificate selection still use secp384r1 if no other certificate is
available.

That said, OpenSSL 1.1.0 by default supports a list of algorithms with
X25519 preferred over P-384, so not setting the curves explicitly is
likely better.

For the record, this is a duplicate of #2033

My understanding:
ECC cert use a curve and the key exchange procedure also use a curve.
These two can be different.
However, if you set
ssh_ecdh_curve X25519;
into the Nginx under openssl 1.1.0c
the Nginx/openssl will use X25519 to both the two places above .which is not correct because X25519 can only be used in key exchange.

My solution is (only suitable for my config):

  1. Do not set ssh_ecdh_curve , then the nginx will use its default settings, which can reach my goals because chrome will prefer X25519, but this is not recommended because you can not control the nginx's default settings(seems to be P-256).
  2. explicitly set ssh_ecdh_curve X25519:spec384r1; this is perfect for me because chrome and other browsers forked from chrome(I mean use similar kernel will prefer X25519)

explicitly set ssh_ecdh_curve X25519:spec384r1;

Sorry to comment on this rather old issue. But shouldn't it be ssl_ecdh_curve X25519:secp384r1 instead?
NGINX does not have a directive that starts with ssh and the curve is not spec384r1 but secp384r1.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

enriquejcobo picture enriquejcobo  路  3Comments

kirin10000 picture kirin10000  路  3Comments

mattcaswell picture mattcaswell  路  4Comments

sanjibbaral435 picture sanjibbaral435  路  3Comments

Legends picture Legends  路  3Comments