OpenSSL Usage Notes

The openssl program is basically a dumping ground for all sorts of SSL related functions. What it does varies wildly based on the parameters passed in. Here is a usage summary of some of the more useful functions.

Notes

  • SSL is based on RSA asymmetrical encryption (aka public key encryption)
  • Two files are created; a certificate (the “cert”) and a key
  • The cert is public. It contains information about the cert user (i.e. the “subject”) and the organization that “signed” the cert (i.e. the “issuer”). It also contains an encrypted hash “signature” of the cert contents.
  • “Signing” a cert means that a secure hash of the cert is calculated and the secure hash is encrypted with the signing authority's (the “issuer”) secret key. This encrypted hash is then appended to the certificate.
  • Check the integrity of the cert by calculating the secure hash of the cert and comparing it with the decrypted signature.
  • Decrypt the signature by using the public key of the issuer.
  • Cert trust is based on whether or not you trust the issuer and his ability to vouch for the “subject”

Definitions

cert Public X.509 format certificate. Contains subject's public key.
DER Binary format used for keys
issuer Entity that signs a cert
key Subject's secret key
PEM Straight ASCII (BASE64) format of a binary cert or key
sign Calculate a secure hash and encrypt hash with issuer's private key
subject The entity (person or organization) described in the cert

File Types

.pem Stands for PEM, Privacy Enhanced Mail; it simply indicates a base64 encoding with header and footer lines. Mail traditionally only handles text, not binary which most cryptographic data is, so some kind of encoding is required to make the contents part of a mail message itself (rather than an encoded attachment). The contents of the PEM are detailed in the header and footer line - .pem itself doesn't specify a data type - just like .xml and .html do not specify the contents of a file, they just specify a specific encoding.
.key Can be any kind of key, but usually it is the private key - OpenSSL can wrap private keys for all algorithms (RSA, DSA, EC) in a generic and standard PKCS#8 structure, but it also supports a separate 'legacy' structure for each algorithm, and both are still widely used even though the documentation has marked PKCS#8 as superior for almost 20 years; both can be stored as DER (binary) or PEM encoded, and both PEM and PKCS#8 DER can protect the key with password-based encryption or be left unencrypted.
.crt or .cer Stands simply for certificate, usually an X509v3 certificate, again the encoding could be PEM or DER; a certificate contains the public key, but it contains much more information (most importantly the signature by the Certificate Authority over the data and public key, of course).
.csr or .req Stands for Certificate Signing Request as defined in PKCS#10; it contains information such as the public key and common name required by a Certificate Authority to create and sign a certificate for the requester, the encoding could be PEM or DER (which is a binary encoding of an ASN.1 specified structure)

Important OpenSSL Commands and Options

openssl command [ command_opts ] [ command_args ]
Standard Commands
ca Certificate Authority (CA) Management.
req X.509 Certificate Signing Request (CSR) Management.
x509 X.509 Certificate Data Management.
Digest Commands
md5 MD5 Digest
sha1 SHA-1 Digest
sha256 SHA-256 Digest
Common Options
-config filename Configuration file to use.
-nodes Not the English word “nodes”, but rather is “no DES”. When given as an argument, it means OpenSSL will not encrypt the private key in a PKCS#12 file. To encrypt the private key, you can omit -nodes and your key will be encrypted with 3DES-CBC. To encrypt the key, OpenSSL prompts you for a password and it uses that password to generate an encryption key.
-key file Use the private key contained in file
-keyform arg Key file format
CA Options
-in filename Input filename containing a single certificate request to be signed by the CA.
-ss_cert filename A single self-signed certificate to be signed by the CA.
-out filename File to output certificates to.
-cert The CA certificate file.
-selfsign Issued certificates are to be signed with the key the certificate requests were signed with (given with -keyfile).
-days arg The number of days to certify the certificate for.
REQ Options
-inform arg Input format - DER or PEM
-outform arg Output format - DER or PEM
-in arg Input file
-out arg Output file
-pubkey Output public key
-keyout arg File to send the key to
-new New request
-x509 Output a x509 structure instead of a cert request
-days Number of days a certificate generated by -x509 is valid for
-newkey rsa:bits Generate a new RSA key of 'bits' in size
-text Text form of request
-noout Do not output REQ

Generate a public / private RSA key pair

This just generates a matched pair of public and private keys using the RSA algorithm. Once generated these keys can be used for other SSL activities such as encryption certificate signing.

openssl genrsa -out my_key_name.key 2048

Both the public and private keys reside in the key file. Hold this file near and dear, especially if it isn't password protected. Extract the public key portion of this with RSA command.

openssl rsa -in my_key_name.key -outform PEM -pubout -out my_public_key_name.pem

Build a "root" (i.e. self-signed) Certificate of Authority

openssl ca -new -x509 -extensions v3_ca -keyout CA-key.pem -out CA-cert.pem -days 3650 -config openssl.cnf -nodes

Build a Certificate Signing Request (CSR)

Here is a basic version of CSR generation

openssl req -days 3650 -nodes -new -x509 -keyout ca.key -out ca.crt -config openssl.config

Cheap SSL Security has a guide to CSR generation for Apache. They recommend:

openssl req -new -newkeys rsa:2048 -nodes -keyout baggerman.org.key -out baggerman.org.crt

This makes new RSA keys. To use an existing key use this form:

openssl req -new -key key_file_name.pem -out baggerman.org.csr

This doesn't seem to support Subject Alternative Names, though. Here is some good info on how to add SAN to openssl.conf. And here is a pretty good CSR builder that knows about SANs. Here is what needs to be added to the openssl.cnf file.

[ req ]
req_extensions          = v3_req # The extensions to add to a certificate request
[ v3_req ]
subjectAltName = @alt_names
[alt_names]
DNS.1 = www.baggerman.org
DNS.2 = baggerman.org
IP.1 = 198.89.126.181

Check the CSR with the following command:

openssl req -text -noout -in baggerman.org.csr

There is also a good CSR decoder at SSL Shopper

Submit a Certificate Signing Request (CSR)

Use the .csr file to submit a signing request to a certificate provider like CheapSSL. Save the returned certificate into to a certificate file (.cer) Also save the intermediate certificate advisory file if necessary.

Or self-sign a Certificate Signing Request (CSR)

openssl ca -days 3650 -out key.crt -in key.csr -config  openssl.cnf

View a Certificate

openssl x509 -in certificate.crt -text -noout

Convert a Certificate to PEM format

openssl x509 -inform der -in certificate.cer -out certificate.pem

If you get an error it probably means the certificate is already in PEM format

Self-sign a Certificate

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout mysitename.key -out mysitename.crt

Configure Apache

Good notes at

Setup default SSL settings outside of a virtual host. Current recommended config (from https://cipherli.st/) is:

SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
SSLProtocol All -SSLv2 -SSLv3
SSLHonorCipherOrder On

Be sure to set:

SSLCertificateKeyFile   "/etc/pki/tls/private/csr.key"
SSLCertificateFile      "/etc/pki/tls/certs/web_server_cert.cer"
SSLCertificateChainFile "/etc/pki/tls/certs/intermediate.pem"