10
votes

I was wondering if there are minimum key-generation requirements for ECDHE-ECDSA-AES128-GCM-SHA256 and ECDHE-ECDSA-AES128-GCM-SHA256? I am trying to get a TLS client and server using one of the above algorithms to connect to each other and keep receiving 'no shared cipher errors'. I created a CA for signing client and server certs, and attempted connecting with just openssl and also in node.js. I am running the client and server on localhost (127.0.0.1) to eliminate any other possible problems.

Here is what I have done so far:

CA key pair creation:

  $ openssl genrsa -out ca-key.pem 4096
  $ openssl req -new -x509 -days 365 -key ca-key.pem -out ca-cert.pem

Server / client key pair creation:

  $ openssl genrsa -out server-key.pem 4096
  $ openssl req -new -key server-key.pem -out server-csr.pem
  $ openssl x509 -req -days 365 -in server-csr.pem -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem 

  $ openssl genrsa -out client-key.pem 4096
  $ openssl req -new -key client-key.pem -out client-csr.pem
  $ openssl x509 -req -days 365 -in client-csr.pem -CA ca-cert.pem -CAkey ca-key.pem -set_serial 02 -out client-cert.pem

I was originally attempting to connect to a node.js server from the command line (tls.createServer() with options: ciphers: 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256'), but to eliminate node suspicion I fell back to openssl for both client and server creation.

The following commands CORRECTLY connect for client and server and states it is using a cipher of "New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384":

$ openssl s_server -accept 8888 -cert server-cert.pem -key server-key.pem -pass stdin -CAfile ca-cert.pem  -state
<password entered here>

$ openssl s_client -connect 127.0.0.1:8888 -cert client-cert.pem -key client-key.pem -pass stdin -CAfile ca-cert.pem -state
<password entered here>

With the shared cipher information as follows:

Shared ciphers:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-R
SA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES2
56-SHA:SRP-DSS-AES-256-CBC-SHA:SRP-RSA-AES-256-CBC-SHA:DHE-DSS-AES256-GCM-SHA384
:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA256:DHE-RSA-A
ES256-SHA:DHE-DSS-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:ECD
H-RSA-AES256-GCM-SHA384:ECDH-ECDSA-AES256-GCM-SHA384:ECDH-RSA-AES256-SHA384:ECDH
-ECDSA-AES256-SHA384:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:AES256-GCM-SHA384
:AES256-SHA256:AES256-SHA:CAMELLIA256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES
-CBC3-SHA:SRP-DSS-3DES-EDE-CBC-SHA:SRP-RSA-3DES-EDE-CBC-SHA:EDH-RSA-DES-CBC3-SHA
:EDH-DSS-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-SHA
:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA2
56:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:SRP-DSS
-AES-128-CBC-SHA:SRP-RSA-AES-128-CBC-SHA:DHE-DSS-AES128-GCM-SHA256

The following commands do NOT work when I specify a cipher on the server, or the client and server. Note that the ECDHE-ECDSA-AES128-GCM-SHA256 cipher is listed as shared in the above list.

$ openssl s_server -accept 8888 -cert server-cert.pem -key server-key.pem -pass stdin -CAfile ca-cert.pem -cipher ECDHE-ECDSA-AES128-GCM-SHA256
<password entered here>

<< Server output after client connection attempt >>
Using default temp DH parameters
Using default temp ECDH parameters
ACCEPT
ERROR
2674688:error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher:s3_srvr.c:1353:
shutting down SSL
CONNECTION CLOSED
ACCEPT


$ openssl s_client -connect 127.0.0.1:8888 -cert client-cert.pem -key client-key.pem -pass stdin -CAfile ca-cert.pem -cipher ECDHE-ECDSA-AES128-GCM-SHA256
<password entered here>

<<client output after connection attempt>>
CONNECTED(00000003)
2674688:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:s23_clnt.c:708:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 166 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---

Does anyone have any ideas? Thanks in advance!

1
What version of openssl are you using? openssl versionPaddy Carroll
I'm using OpenSSL 1.0.1 14 Mar 2012aspergillusOryzae
Also be sure to use a "named curve". For the details, see Elliptic Curve Cryptography | Named Curves on the OpenSSL wiki.jww

1 Answers

17
votes

You are making the wrong kind of key with

 openssl genrsa -out ca-key.pem 4096 

You need to use ecparam

openssl ecparam -name secp521r1 -out ca-key.pem -genkey

and

openssl ecparam -name secp521r1 -out client-key.pem -genkey

genrsa generates an RSA key that, when used with ECDHE, authenticates the Elliptic Curve Diffie Hellman key Exchange (ECDHE).

The ECDSA in ECDHE-ECDSA-AES128-GCM-SHA256 means you need the Elliptic Curve Digital Signature Algorithm to authenticate that key. Because you don't have those kind of keys, the command fails. However, ECDHE-RSA-AES256-GCM-SHA384 works because it uses RSA keys which you have.

You are getting sha384 because openssl picks the strongest cipher suite and all things being equal sha384 is better than sha256. You can override this, and it looks like you did so with --cipher.

Note you may want to use a different curve. You can get the full list with

openssl ecparam -list_curves

Out of curiosity, why that specific cipher suite? ECDHE and ECDSA are state of the art, but sha256 is just standard, and well AES 128 is certainly good enough, people tend to use 256 if they are being as cautious as the ECDHE and ECDSA stuff implies.