search by tags

for the user

adventures into the land of the command line

ecdhe-ecdsa ssl certs

in a previous post, which i’m renaming as i confused myself, i generated an ecdhe-rsa ssl cert. an elliptic curve diffie-hellman ephemeral certificate, with an rsa key exchange mechanism.

this post is about creating the same certificate, but with an elliptic curve digital signature algorithm key exchange mechanism.

first first off, change into the /etc/ssl/ directory

$ cd /etc/ssl

first off, check your curvessss

$ openssl ecparam -list_curves

  secp384r1 : NIST/SECG curve over a 384 bit prime field
  secp521r1 : NIST/SECG curve over a 521 bit prime field
  prime256v1: X9.62/SECG curve over a 256 bit prime field

i’m just gonna go with prime for now, but it’s up to you. you can choose by which is most widely supported, or which is best for security

create you own CA auth key

$ openssl ecparam -genkey -name prime256v1 -out mytest_ca.key

create a CA certificate

$ openssl req -x509 -new -SHA256 -nodes -key mytest_ca.key -days 365 -out mytest_ca.crt

it’ll ask you for certificate info, fill it in. this info is available to users in their browsers when they click on certificate information in the green padlock next to the url they are visiting

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:AU
State or Province Name (full name) []:Victoria
Locality Name (eg, city) [Default City]:Melbourne
Organization Name (eg, company) [Default Company Ltd]:My Company
Organizational Unit Name (eg, section) []:Ops
Common Name (eg, your name or your server's hostname) []:www.mysite.com
Email Address []:[email protected]

next, create an auth key for the server

$ openssl ecparam -genkey -name prime256v1 -out mytest_server.key

create a certificate signing request for the server

$ openssl req -new -SHA256 -key mytest_server.key -nodes -out mytest_server.csr

again with the infos

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:AU
State or Province Name (full name) []:Victoria
Locality Name (eg, city) [Default City]:Melbourne
Organization Name (eg, company) [Default Company Ltd]:My Company
Organizational Unit Name (eg, section) []:Ops
Common Name (eg, your name or your server's hostname) []:www.mysite.com
Email Address []:[email protected]

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

it’s important that the common name matches the url for which it is being requested for. if you have many subdomains, the common name can also be wildcarded so that the cert will work for any subdomain like so:

*.mysite.com

self sign the server key, using the CA key and cert you created just before

$ openssl x509 -req -SHA384 -days 365 -in mytest_server.csr -CA mytest_ca.crt -CAkey mytest_ca.key -CAcreateserial -out mytest_server.crt

because at the time of this writing, ecdhe-ecdsa is relatively newish (i might just be slow), there are some things that will make you scratch your head when you try to use it and it doesn’t work.

curl - you’ll need to specify the cipher if you’re on version 7.19.7-46.el6

$ curl -vi --ciphers ecdhe_ecdsa_aes_128_sha -X GET https://my.site.com

python - if you’re using 2.6 (don’t judge me) and not 2.7 or above, you’ll get some problems because even though you may have openssl-1.0.1e-42.el6_7.2 installed, python 2.6 only supports TLSv1… so you’ll have to upgrade to 2.7+ as urllib and by extension requests will not support the latest protocols.

lastly you’ll need your dhparam file

$ openssl dhparam -out myapp.pem 2048

at the end of this exercise, you should have 7 new files in /etc/ssl

$ ls -l /etc/ssl

-rw-r--r--  1 root root  960 Feb 29 16:39 mytest_ca.crt
-rw-r--r--  1 root root  302 Feb 29 16:39 mytest_ca.key
-rw-r--r--  1 root root   17 Feb 29 16:39 mytest_ca.srl
-rw-r--r--  1 root root  424 Feb 29 16:40 myapp.pem
-rw-r--r--  1 root root  843 Feb 29 16:39 mytest_server.crt
-rw-r--r--  1 root root  558 Feb 29 16:39 mytest_server.csr
-rw-r--r--  1 root root  302 Feb 29 16:39 mytest_server.key

reference the the important ones in your nginx config, restart it and you’re all set

$ vim /etc/nginx/conf.d/myapp.conf


server {
    listen                      443;
    server_name                 my.server.name;
    access_log                  /var/log/nginx/nginx_access.log;
    error_log                   /var/log/nginx/nginx_error.log;

    ssl                         on;
    ssl_certificate             /etc/ssl/mytest_server.crt;
    ssl_certificate_key         /etc/ssl/mytest_server.key;
    ssl_protocols               TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers   on;
    ssl_ciphers                 "ECDHE-RSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-ECDSA-AES128-SHA256 ECDHE-RSA-AES128-SHA ECDHE-ECDSA-AES128-SHA ECDHE+ECDSA+AES128+SHA EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4 !MEDIUM";
    ssl_dhparam                 /etc/ssl/myapp.pem;
    keepalive_timeout           10;
    ssl_session_cache           shared:SSL:10m;
    ssl_session_timeout         10m;

    location / {
        proxy_pass              http://0.0.0.0:5001;
        proxy_next_upstream     error timeout invalid_header http_500 http_502 http_503 http_504;
        proxy_set_header        Host $http_host;
        proxy_set_header        X-Real-IP $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header        X-Forwarded-Proto $scheme;
        add_header              Front-End-Https on;
    }

    location /static {
        root /var/www/myapp;
    }
}


$ sudo /etc/init.d/nginx restart