Generating your own keys with S/MIME

When I need to renew my S/MIME certificates in a few years I will have forgotten everything I did today, so here are my notes.

If you want to encrypt & sign your email with an S/MIME certificate then you may find this useful. There aren’t a huge number of resources online explaining this particular process, or at least the ones I found seemed to be contradictory or many years old.

Please note: this is not a guide on how to get a free S/MIME certificate. Every Certificate Authority (CA) offering free personal email certificates that I’ve seen generates the private key for you. I understand that they do this to simplify support and cut costs, but frankly you’re nuts if you’d trust that sort of setup.

The process I detail below involves generating your own RSA key pair, then having a CA sign it. I used because I’ve never had a problem with them and they support uploading your own key for cheap personal email certificates.

These instructions assume you have a relatively recent version of the openssl commandline tools. They are tested with version 0.9.8x.

These are the steps we’ll follow:

  1. Create a public/private RSA key pair & Certificate Signing Request (CSR)
  2. Upload the CSR to the CA to be signed
  3. Download the signed certificate from the CA
  4. Merge your private key into the signed certificate to create an encrypted PKCS12 file to safely store the final key pair

Generate your public/private key pair & CSR

Use the openssl req (request) command to generate your RSA key pair then output a CSR (which contains the public key) and an encrypted private key:

openssl req \
	-out send_to_CA.csr \
    -newkey rsa:4096 \
    -keyout private.key

This will print a sequence of dots to your terminal while it works, then prompt you for a password to encrypt the private key file:

Generating a 4096 bit RSA private key
writing new private key to 'private.key'
Enter PEM pass phrase:

Note: this password is only used to encrypt this particular private key file, and later on it will be superceded by another password to encrypt the entire PKCS12 bundle. You can add the -nodes switch to omit the encryption if you prefer, although this will write an unencrypted form of your private key to disk (not ideal).

Upload the CSR to your Certificate Authority

This stage obviously differs for each CA. Usually you receive an email from the CA notifying you of the completion of the verification process; this email contains a link to a form where you can copy/paste the contents of the send_to_CA.csr file.

Download your signed certificate

In the case of GlobalSign this is a CER file following the pattern PC[YYYY][MM][DD][1234].cer. You may get a CRT file instead, depending on your authority’s preference. CRT & CER are functionally equivalent formats and openssl seems not to care which is used.

Merge the signed certificate and private key with the openssl pkcs12 command:

openssl pkcs12 -export \
	-in PC201308301234.cer \
	-inkey private.key \
    -out bundle.p12

Enter pass phrase for private.key:
Enter Export Password:
Verifying - Enter Export Password:

You will be prompted for the password to decrypt the private key file, then for a new password to use to encrypt the PKCS12 bundle (I used the same for both).

The strength of this password is vitally important so I typically generate a random 40 character string with spaces, punctuation etc. You can set your OS keychain or gpg-agent to cache the password for you, so don’t worry about remembering it.

Note: some authorities (such as GlobalSign) use intermediate certificates. If yours does then you will need to include it in your PKCS12 bundle. You should look for a PEM format intermediate certificate and include it with the -certfile switch like so:

openssl pkcs12 -export \
	-in PC201308301234.cer \
	-inkey private.key \
    -certfile gspersonalsign2g2ocsp.txt \
    -out bundle.p12

Using the PKCS12 certificate bundle

Now that you have your certificate file (bundle.p12) you can delete all of the other files (and you should securely delete your naked private key file).

Installing the certificate bundle is usually simple so I’m not going to explain how you do it in every combination of operating system and mail client.

If you’re using Linux or BSD then you’re probably using GnuPG to handle S/MIME certs in which case you’d run gpgsm --import bundle.p12. See the GnuPG docs for more detail.

On a Mac you can just double click the bundle.p12 file and Keychain Access will import it and prompt you for the password. You can also use S/MIME on iOS devices.

Please remember to save a backup copy of your bundle.p12 file somewhere safe. I attach it to the password entry in my keepass database – lastpass probably has a similar feature.