OpenSSL Cheat Sheet - Todd Warner ------------------------------------------------- $Date: 2006-06-02 16:02:42 -0400 (Fri, 02 Jun 2006) $ NOTE: the platform for discussion here is Red Hat Enterprise Linux and Fedora. For everything else, you are on your own. The world of Secure Socket Layers (SSL) is far more complex than it needs to be. But even in its dumbed down version, it is a bit much to swallow. If you understand the comcepts of Public Key Infrasture (PKI) and SSL, then this cheat sheet will help you wade through the morass of options that is OpenSSL. After Oracle's Web Applications, OpenSSL's user interface is arguably the worst designed ever. Or at least, from what I have ever worked with. So, you understand PKI and SSL in concept? If not, read more about it and come back. About the best introduction to SSL I have read was written by me. :) Currently (2006), this is Chapter 3, "SSL Infrastructure", of the Red Hat Network Client Configuration Guide: https://rhn.redhat.com/help/about.pxt If you use RHN Satellite or RHN Proxy, use the rhn-ssl-tools instead of these instructions. You will thank me. :) Else, continue. NOTE: there is "A Summary" at the bottom of this file that concisely summarizes these steps. Getting Started --------------- OpenSSL prompts you for field values, but I like a configuration file that I can save and tweak as necessary. I am assuming the "openssl" package installed on your Linux box. (1) Create a new SSL working directory and cd into it: mkdir ssl cd ssl (2) Copy over the default configuration file. FC3, RHEL 4, and below: cp /usr/share/ssl/openssl.cnf . FC5: cp /etc/pki/tls/openssl.cnf . NOTE: I don't know about other versions of Red Hat or Fedora. (3) Edit all the demographic information for your organization/group. (4) Change the policy setting from policy_match to policy_anything Certificate Authority Key/Certificate Generation ------------------------------------------------ Only use this section if you plan to be your own Certificate Authority. If your infrastructure is to be used internally and you have a sane mechanism to deploy and configure the public CA certificate to your infrastructure clients, this is the way to go. If you do not, skip this section and use a third party Certificate Authority instead: http://www.cacert.org/ - FREE! Some meager documentation. http://www.verisign.com/ssl/index.html - Expensive! If continuing, you have decided to be your own CA and need a CA private key and public CA certificate. While still in the ssl directory... (1) Create a "ca" directory: mkdir ca (2) Edit openssl.cnf to have CA_defaults land everything in the ssl directory. Make it look something like this (I am user "taw"): dir = /home/taw/ssl # Where everything is kept and your pwd certs = $dir/ # Where the issued certs are kept crl_dir = $dir/ # Where the issued crl are kept database = $dir/index.txt # database index file. new_certs_dir = $dir/ # default place for new certs. certificate = $dir/ca/ca.crt # The CA certificate serial = $dir/serial # The current serial number crl = $dir/ca.crl # The current CRL private_key = $dir/ca/ca.key # The private key RANDFILE = $dir/ca/.rand # private random number file (3) Zero out/create index.txt and initialize the serial file: cp /dev/null index.txt echo 01 > serial (4) Generate the private key: openssl genrsa -aes256 2048 -config openssl.cnf > ca/ca.key chmod 0600 ca/ca.key (5) Generate the CA certificate: NOTES: - the "common name" for the CA public certificate is something like "Example, Inc. Certificate Authority"): - in this example, we create a CA public certificate that lasts 1825 days, or approximately, 5 years. openssl req -new -x509 -days 1825 -key ca/ca.key \ -out ca/ca.crt -config openssl.cnf (6) Make this CA certificate publically available for clients or deploy it directly. Server-Side Key, and Certificate Signing Request (CSR) Generation ----------------------------------------------------------------- In client-server communication, the server application (for example, a web-server) needs a key and certificate. The key remains secret to that server, but the certificate is public and is cryptographically related to both the secret key and the CA's public key. Since the you may not be the CA, an extra step is required in the process. That extra step is the generation of a Certificate Signing Request. (1) Generate the server application's secret key: While still in the SSL directory... There are two ways to do this. You can password encrypt your secret key. Or you can leave the server key password-less and therefore unencrypted. In most cases (for example a web-server like Apache) the application, once given a password, will decrypt the key and load it into memory anyway. Therefore, most of the time, I see no need to password encrypt the server key. Generate the server private key (passworded/encrypted version): openssl genrsa -aes256 2048 > server.key Generate the server private key (unencrypted version): openssl genrsa 2048 > server.key (2) Generate the certificate signing request (CSR): NOTE: the common name for the server-side SSL certificate needs to be the hostname of the machine as the client sees it. openssl req -new -key server.key -out server.csr -config openssl.cnf A different way - these two steps can be combined into one, though I prefer being explicit: openssl req -nodes -new \ -keyout private.key -out server.csr \ -config openssl.cnf Sign the Certificate Signing Request (CSR), Generating a Server-side Public SSL Certificate --------------------------------------------------------------------------- If you skipped the first section and intend to use a 3rd party Certificate Authority (CA), this step is easy: create an account with that 3rd party and follow their process of authentication and send in your server.csr for them to sign. You will receive a server-side public SSL certificate in return. If you are your own Certificate Authority (CA). (1) Using the CA secret key and public certifice, sign the certificate signing request and generate a public server SSL certificate: openssl ca -in server.csr -out server.crt -config openssl.cnf Organization of Keys, CSRs and Certificates, and Secure Storage --------------------------------------------------------------- Server key sets are hostname specific generally. If you followed these steps precisely, the key set (server.{key,csr,crt}) sits in the ssl/ directory, and the CA key pair sits in the ssl/ca directory. Over time, most organizations create multiple server-side key sets. Therefore, I recommend extending this directory structure with hostname specific information and storing the appropriate key sets in the hostname directories. The hierarchy will look something like this: ssl/ ssl// ssl//server.key ssl//server.csr ssl//server.crt ssl// ssl//server.key ssl//server.csr ssl//server.crt ssl/ca/ ssl/ca/ca.key ssl/ca/ca.crt This is far simpler than openSSL's default directory structure and makes much more sense IMHO. Deploy the server.* key set appropriately for your server. Once complete, I recommend backing up that SSL file tree to 2 copies of removable media and placing them into a physically secure location. Remember that CA password! Finally delete that directory tree, restoring only when you need to create more server key sets. A Summary: ========== Getting Started --------------- - mkdir ssl; cd ssl - copy over and edit openssl.cnf: - cp /usr/share/ssl/openssl.cnf . - s/policy_match/policy_anything - update organizational information Being Your Own Certificate Authority (CA) ----------------------------------------- - edit openssl.cnf: update/simplify directory structure - cp /dev/null index.txt echo 01 > serial - Private key: openssl genrsa -aes256 2048 -config openssl.cnf > ca/ca.key chmod 0600 ca/ca.key - Public CA Certificate (5 year expiration example): openssl req -new -x509 -days 1825 -key ca/ca.key \ -out ca/ca.crt -config openssl.cnf Server-Side SSL Private Key and Certificate Signing Request (CSR) ----------------------------------------------------------------- - server.key: openssl genrsa -aes256 2048 > server.key # password/encrypted version ...or... openssl genrsa 2048 > server.key # unencrypted version - server.csr (common name == hostname as client sees it): openssl req -new -key server.key -out server.csr -config openssl.cnf Server-Side SSL Public Certificate (server.crt) ----------------------------------------------- openssl ca -in server.csr -out server.crt -config openssl.cnf Build Tree Organization ----------------------- Create directories and move server.* files appropriately ssl//server.{key,csr,crt} ssl/ca/ca.{crt,key} I hope you found this helpful.