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 []:me@mail.com
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 []:me@mail.com 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