SSL/TLS Certificate Cheat Sheet
I need to overhaul this to become a cheat sheet.
Also, I just found out about letsencrypt.org, and I need to try them out (and donate if I like them).
The usual order of things when establishing a new site is to ...
- Create a private key
- Create a Certificate Signing Request (CSR)
- Submit the CSR to a Certification Authority (CA)
- Receive a signed certificate from the CA
- Install the key and certificate on the server
If you are making a certificate for your own purposes and don't need it signed (you can store exceptions for your own certificate), then ...
- Create a private key
- Create a self-signed certificate
- Install the key and certificate on the server
Unless otherwise specified, certificate and key files are in X.509 PEM format. Apache httpd uses this format.
Create (Private) Key
This creates a 2048-bit RSA key (with no password protection).
openssl genrsa -out ${NAME}.key 2048
Create Certificate Signing Request (CSR)
To get a signed certificate from a Certification Authority, you must create and submit a CSR. This command creates one with SHA-256.
You will be prompted for the identity information to include in the certificate. For web sites, it is important that the "Common Name" matches the FQDN of the site.
openssl req -new -sha256 -key ${NAME}.key -out ${NAME}.csr
Create Self-Signed Certificate
If you don't need your certificate signed by Certification Authority, you can just create a self-signed certificate from your key. This command creates a self-signed certificate that expires in ten years.
You will be prompted for the identity information to include in the certificate. For web sites, it is important that the "Common Name" matches the FQDN of the site.
openssl req -new -x509 -key ${NAME}.key -out ${NAME}.crt -days 3650
Display Certificate Signing Request (CSR)
To display the contents of a CSR:
openssl req -in ${NAME}.csr -text -noout | more
Display Certificate
To display the contents of a certificate:
openssl x509 -in ${NAME}.crt -text -noout | more
Check Private Key
If for some reason you want to check the validity of a private key, you can use this command.
openssl rsa -in ${NAME}.key -check
Convert PFX/P12 to PEM and Private Key
This command converts a PFX file to PEM format. It's important to note that the output file will contain the private key and all of the certificates. This probably can't be used directly by Apache httpd, and it also makes it impossible to set file security appropriatly for the private key versus the public certificates. You can use a text editor to divide up the pieces.
openssl pkcs12 -in ${NAME}.pfx -out ${NAME}.crt+key -nodes
Alternatively, you can execute separate commands to extract each component. If there are multiple CA certificates, they will all end up in the output file of the last command.
openssl pkcs12 -in ${NAME}.pfx -out ${NAME}.key -nodes -nocerts openssl pkcs12 -in ${NAME}.pfx -out ${NAME}.crt -nodes -clcerts -nokeys openssl pkcs12 -in ${NAME}.pfx -out CAcert.crt -nodes -cacerts -nokeys
Convert PEM and Private Key to PFX/P12
This bundles up a private key, certificate, and CA certificate into a single PFX file.
openssl pkcs12 -export -out ${NAME}.pfx -inkey ${NAME}.key -in ${NAME}.crt -certfile CAcert.crt
Verify Match
To verify that the key matches the certificate and/or the CSR, execute the following. The md5 hashes should match.
openssl x509 -noout -modulus -in ${NAME}.crt | openssl md5 openssl rsa -noout -modulus -in ${NAME}.key | openssl md5 openssl req -noout -modulus -in ${NAME}.csr | openssl md5
Okay, so I create SSL certificates infrequently enough that I can't just remember the procedure and syntax for doing so. However, I do it often enough to warrant a web page on the subject -- especially since the places I currently refer to may go away some day.
To be clear, this procedure is for Apache with mod_ssl. It is also good for other things that use the OpenSSL library (like IMAP-UW).
Creating an SSL Key and CSR
Okay, I normally do this in the /usr/local/certs directory. The steps I follow are to:
- Select a passphrase for the key, and because I'll never use it again, store it in a little text file with a .pw extension
- Create the private key
- Create a version of the private key that doesn't contain the passphrase, since I don't want to manually type passphrases every time the web server is started
- Create a Certificate Signing Request (CSR)
The only trick to this is that, when creating the CSR, the "Common Name" must be the FQDN of the web site it will be associated with. For example, if the certificate will be used at "https://www.coreth.com/", the Common Name should be set to "www.coreth.com".
The CSR is sent to the signing authority, and they sign it and send back a certificate.
Below are the exact steps I follow when I do this (replace "server" with a name associated with your web site):
vi server.pw openssl genrsa -des3 -out server.key.secure 1024 openssl rsa -in server.key.secure -out server.key openssl req -new -key server.key -out server.csr
Self-Signed Certificates
To sign your own certificates, you need to create a Certificate Authority. You should only have to do this once (well, every 365 days perhaps).
vi ca.pw openssl genrsa -des3 -out ca.key 1024 openssl req -new -x509 -days 365 -key ca.key -out ca.crt
Note that there is nothing magic about 365. If you don't want to mess with this every year, you can sign it for a much larger number of days.
If you already have a ca.crt, you can use the sign.sh script to sign CSRs. The sign.sh script is found in the mod_ssl source distribution, and I normally stick it in /usr/local/bin for ease of use. The script signs the CSR and outputs a server.csr file.
sign.sh server.csr
Apache Configuration
Yeah, I should probably write about how to reference the files from Apache, but I'm too lazy, and there should be good examples in the config file already. Maybe later.
FAQ
There is a FAQ over at modssl.org which has some good information about certificates and using the openssl utility.
Simple Self-Signed Certificates?
Could it really be this simple?
openssl genrsa -out server.key 2048 openssl req -new -x509 -key server.key -out server.cert -days 3650
Be sure to supply the FQDN of the web site when asked for the Common Name.