Friday 22 March 2013

Create your own S/MIME email certificates with Openssl

Following on from creating my own Certificate Authority for signing internal https connections as covered in a previous post, the same Openssl CA can be used to create certificates for signing emails. This has many of the same benefits and limitations as self signed with SSL certificates for websites. On the plus side it is free and because you control it you can instantly create as many certificates as you desire. It is just as secure cryptographically as a certificate from a big player like Verisign. The negatives are that you will need to convince everybody you deal with to trust your certificates since they will not be automatically trusted and there is no insurance associated with them if something goes wrong. For internal use and testing they are therefore perfectly fine, for external customer facing use you are probably better off paying to get a certificate from one of the commercial players in the market.

Update the Certificate Authority for S/MIME

So assuming you have followed my previous guide and have a working Certificate Authority there is one change to make. Copy the openssl.cfn file to openssl-users.cnf, open the new file in a text editor and in the [ usr_cert ] section comment change the nsCertType as follows:
# nsCertType = server  # <---- comment out this line
nsCertType = client, email # <---- un-comment this line
Certs created will now be defaulting to client and email use so they can be used as part of  vpn or similar and also encrypt and sign emails.

Create Private Key and CSR

We can now create a private key and csr for the user in question:
$ openssl req -config openssl-users.cnf -new -newkey rsa:2048 -keyout private/Users_Name.key -out csr/Users_Name.csr -days 365
Note that the only difference here from my server key generation is that I have not added the -nodes command. This means that the private key will have a password on it that needs to be entered when used. My logic is that server keys are both on more secure machines and might need to reboot for updates on a schedule so requiring a password there might not be practical. For a users email key it will be on a normal workstation so more exposed to security risks and also you will always be there to enter the password since you will have just typed out an email!

Answer the wizard with the values you wish to have on your certificate. The "common name" should be your actual name and make sure the email address is exactly correct.

Create Certificate and Convert to PCKS12 Format

Next you need to sign the csr with the CA key:
$ openssl ca -config openssl-users.cnf -out certs/Users_Name.crt -infiles csr/Users_Name.csr
Check that the cert type is correct to make sure the config changes were done correctly. Next you need to convert this certificate into PCKS12 format so it can be used by email clients. This new file will contain the public certificate and private keys so it needs to be kept secure.
$ openssl pkcs12 -export -in certs/Users_Name.crt inkey private/Users_Name.key -out private/Users_Name.p12

Import Into Email Client

I'll leave this largely as an exercise for the reader because there are too many different email clients to choose from. The two main email clients I use are Outlook and GMail.

  • For Outlook just double click on the *.p12 file - Windows will automatically walk you through adding it to the correct certificate store and configure the security options for you.
  • For gmail it is currently not possible to use S/MIME encryption :( I am guessing that since their Postini service offers encryption they do not want to allow this competition. If you connect another mail client to GMail (Outlook/thunderbird etc) then you can set up the encryption there and it will work fine, it will just show garbage in the gmail web interface.
Remember after importing a certificate you will be able to sign email but not encrypt it! To encrypt email you need to get the public certificate of the person you want to send emails to. The easiest way to sent your public key to someone is to send them a signed email.


  1. "The easiest way to sent your private key ...", really?

    1. Ah. Boy do I feel silly for missing that! Thanks for the heads up I've corrected that to read "public key"

  2. In my case it works with thunderbird but doesn't work with Outlook.