Sunday 10 March 2013

Creating certificates using a custom CA


Assuming you have the CA, here’s the commands –

  # get into our ssl dir cd ~/etc/ssl # make request /System/Library/OpenSSL/misc/ -newreq # sign it /System/Library/OpenSSL/misc/ -sign # decrypt the key openssl rsa -in newkey.pem -out mydomain.key # rename the cert file mv newcert.pem mydomain.pem 


In my previous post I explained how to create a custom CA (certificate authority) on OS X. In this post I’ll explain how to make certificates from your custom CA that you can use in your local webserver to config to develop locally using https without getting warned about self-signed certificates.

Before you go any further, make sure you’ve created a custom CA.

There’s four steps to creating a certificate that can be used in your webserver config –

  1. Create the request for the certificate.
  2. Create the certificate and sign it.
  3. Decrypt the keyfile so that you can use it in your webserver config without having to enter the decryption password when you restart your server.
  4. Rename the files to give them sensible file names.

Create the Request

The most important question you’ll answer in when you run the command to create the request is the “common name” - this should be the domain name for which you want the certificate to apply to. I suggest entering a wildcard like this * because it’ll work for any subdomain.

When you run the command to create the certificate, you’ll be asked for a password; remember it.

 # get into our ssl directory cd ~/etc/ssl/ # make the request /System/Library/OpenSSL/misc/ -newreq # You'll be asked a few questions and  a password. # After which, If all goes well you should see something like this Request is in newreq.pem, private key is in newkey.pem 

Create the certificate & sign

Now you have to sign the certificate. When you enter the below command and then you’ll have to enter the password for the original CA your created (I did tell you to remember this!).

 /System/Library/OpenSSL/misc/ -sign 

If all goes well you should see something like this

 Using configuration from /System/Library/OpenSSL/openssl.cnf Enter pass phrase for ./demoCA/private/cakey.pem: Check that the request matches the signature Signature ok # # snipped out the certificate details # Data Base Updated Signed certificate is in newcert.pem 

You should now have three files in your ~/etc/ssl directory

  • newcert.pem
  • newkey.pem
  • newreq.pem

Decrypt the keyfile

Your last task is to decrypt the key file so that you can use it in your webserver config. If you’d been paying attention when you created these files you’d notice that the keyfile was encrypted using an RSA algorithm. To decrypt this, we’re going to use openssl –

 # cd into the ssl dir cd ~/etc/ssl # decrypt - replace mydomain with your domainname! openssl rsa -in newkey.pem -out mydomain.key 

Just incase it’s not obvious, having decrypted keyfiles is generally a very bad idea, but since this is just for our local development it’s not really a super problem. However, you don’t want to leave decryption keys for production servers lying around, that would be super, super, super sucky of you.

Sensible file names

In our webserver config we need two files, the actually certificate (currently called newcert.pem) and the decrypted keyfile. Let’s rename the file newcert.pem to match our keyfile naming convention –

 # just like above - change mydomain for your actual domain name! mv newcert.pem mydomain.pem 

Now you’re done.

Bonus - apache and nginx config

Here’s some sample config for Apache –

 # you only need this once NameVirtualHost *:443 # # the virtualhost conf      ServerName     SSLStrictSNIVHostCheck off     SSLEngine on     SSLProtocol -all +TLSv1 +SSLv3     SSLCipherSuite HIGH:MEDIUM:!aNULL:+SHA1:+MD5:+HIGH:+MEDIUM     SSLCertificateFile /Users/jcurle/etc/ssl/jamiecurle.pem     SSLCertificateKeyFile /Users/jcurle/etc/ssl/jamiecurle.key     #     # the rest of the config depends on your use      #  

Here’s some sample config for Nginx –

 server {     listen 443;     ssl on;     ssl_certificate /home/obscure/ssl/obscure2.pem;     ssl_certificate_key /home/obscure/ssl/obscure2.key;     server_name;     #     # the rest of the config depends on your use      # 

Now you have no excuse not to develop locally using https and it won’t cost you a penny AND you don’t have to store sensitive production keys unencrypted on your machine.