OpenSSL

Some of this from http://www.coresecuritypatterns.com/blogs/?p=763, http://www.bogpeople.com/networking/openssl.shtml, and (most recently) from https://www.feistyduck.com/library/openssl-cookbook/, which was at the 3rd edition (Feb 2021) when I downloaded it.

End-user Functions

Create key

The Cookbook recommends putting passphrases on key files, but says it doesn’t really worsen security on a production web server to put the passphrase in a file next to the key file — if an attacker is on the system, they can probably extract the decrypted key from the web server memory anyway. The point of the passphrase is to protect the key file when it’s not deployed to your production server.

Create a 2048-bit key pair:

$ openssl genpkey -out fd.key \
-algorithm RSA \
-pkeyopt rsa_keygen_bits:2048 \
-aes-128-cbc
..........................................+++++
...................................................................+++++
Enter PEM pass phrase: ************
Verifying - Enter PEM pass phrase: ************

The key file is text, but inscrutable. You can see what’s actually there using:

$ openssl pkey -in fd.key -text -noout
Enter pass phrase for fd.key: ****************
RSA Private-Key: (2048 bit, 2 primes)
modulus:
00:be:79:08:22:1a:bc:78:3c:17:34:4a:d3:5f:2b:
... [much more output elided]

The “key” is actually a private/public key pair. You can extract just the public part:

$ openssl pkey -in fd.key -pubout -out fd-public.key

Create a password-protected 2048-bit key pair:

openssl genrsa 2048 -aes256 -out myRSA-key.pem

OpenSSL will prompt for the password to use. Algorithms: AES (aes128, aes192 aes256), DES/3DES (des, des3).

Remove passphrase from a key:

openssl rsa -in server.key -out server-without-passphrase.key

Extract public key:

openssl rsa -in blah.key.pem -out public.key -pubout

Getting Certificates

Create Certificate Request and Unsigned Key:

openssl req -nodes -new -keyout blah.key.pem -out blah.csr.pem

More thorough example:

openssl req -new rsa:1024 -node -out myCSR.pem \
    -keyout myPrivCertkey.pem \
    -subj "/C=US/ST=MA/L=Burlington/CN=myHost.domain.com/emailAddress=user@example.com"

Create a self-signed certificate:

openssl req -nodes -x509 -newkey rsa:1024 -days 365 \
    -out mySelfSignedCert.pem  -set_serial 01 \
    -keyout myPrivServerKey.pem \
    -subj "/C=US/ST=MA/L=Burlington/CN=myHost.domain.com/emailAddress=user@example.com"

-x509 identifies it as a self-signed certificate and -set_serial sets the serial number for the server certificate.

Create a single file that contains both private key and the self-signed certificate:

openssl req -x509 -nodes -days 365 -newkey rsa:1024 \
    -keyout myServerCert.pem -out myServerCert.pem \
    -subj "/C=US/ST=MA/L=Burlington/CN=myHost.domain.com/emailAddress=user@example.com"

Fingerprint for Unsigned Certificate:

openssl x509 -subject -dates -fingerprint -in blah.key.pem

Display Certificate Information:

openssl x509 -in blah.crt.pem -noout -text

Creating a PEM File for Servers:

cat blah.key.pem blah.crt.pem blah.dhp.pem > blah.pem

Download some server’s certificate:

openssl s_client -connect www.example.com:443

(then hit ^C out of the interactive shell)

Viewing Certificate Contents

X.509 certificates are usually stored in one of two formats. Most applications understand one or the other, some understand both:

  • DER which is raw binary data.

  • PEM which is a text-encoded format based on the Privacy-Enhanced Mail standard (see RFC1421). PEM-format certificates look something like this:

    -----BEGIN CERTIFICATE-----
    MIIBrjCCAWwCAQswCQYFKw4DAhsFADBTMQswCQYDVQQGEwJBVTETMBEGA1UECBMK
    U29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMQww
    :
    :
    MQAwLgIVAJ4wtQsANPxHo7Q4IQZYsL12SKdbAhUAjJ9n38zxT+iai2164xS+LIfa
    C1Q=
    -----END CERTIFICATE-----
    
    OpenSSL uses the PEM format by default, but you can tell it to process DER format certificates...you just need to know which you are dealing with.
    

The command to view an X.509 certificate in DER format is:

openssl x509 -in filename.cer -inform der -text

Specify -inform pem if you want to look at a PEM-format certificate.

Convert Between Formats

If you have a PEM-format certificate which you want to convert into DER-format, you can use the command:

openssl x509 -in filename.pem -inform pem -out filename.cer -outform der

PKCS12 files

PKCS12 files are a standard way of storing multiple keys and certificates in a single file. Think of it like a zip file for keys & certificates, which includes options to password protect etc.

Don’t worry about this unless you need it because some application requires a PKCS12 file or you’re given one that you need to get stuff out of.

Viewing PKCS12 Keystore Contents:

openssl pkcs12 -in filename.p12 -info

If you have two separate files containing your certificate and private key, both in PEM format, you can combine these into a single PKCS12 file using the command:

openssl pkcs12 -in cert.pem -inkey key.pem -export -out filename.p12

Encrypting and signing things

Signing E-mails:

openssl smine -sign -in msg.txt -text -out msg.encrypted -signer blah.crt.pem -inkey blah.key.pem

Sign some text:

openssl dgst -sign private.key -out signature.asc

Verify signature:

if openssl dgst -verify public.key -signature signature.asc ; then echo GOOD; else echo BAD; fi

Encrypt and decrypt a single file:

openssl aes-128-cbc -salt -in file -out file.aes
openssl aes-128-cbc -d -salt -in file.aes -out file

Simple file encryption:

openssl enc -bf -A -in file_to_encrypt.txt

(password will be prompted)

Simple file decryption:

openssl enc -bf -d -A -in file_to_encrypt.txt

tar and encrypt a whole directory:

tar -cf - directory | openssl aes-128-cbc -salt -out directory.tar.aes
openssl aes-128-cbc -d -salt -in directory.tar.aes | tar -x

tar zip and encrypt a whole directory:

tar -zcf - directory | openssl aes-128-cbc -salt -out directory.tgz.aes
openssl aes-128-cbc -d -salt -in directory.tgz.aes | tar -xz

Certificate Authority Functions

When setting up a new CA on a system, make sure index.txt and serial exist (empty and set to 01, respectively), and create directories private and newcert.

Edit openssl.cnf - change default_days, certificate and private_key, possibly key size (1024, 1280, 1536, 2048) to whatever is desired.

Create CA Certificate:

openssl req -new -x509 -keyout private/something-CA.key.pem \
-out ./something-CA.crt.pem -days 3650

Export CA Certificate in DER Format:

openssl x509 -in something-CA.crt.pem -outform der \
-out something-CA.crt

Revoke Certificate:

openssl ca -revoke blah.crt.pem

Generate Certificate Revokation List:

openssl ca -gencrl -out crl/example.com-CA.crl

Sign Certificate Request:

openssl ca -out blah.crt.pem -in blah.req.pem

Create Diffie-Hoffman Parameters for Current CA:

openssl dhparam -out example.com-CA.dhp.pem 1536

Creating Self-Signed Certificate from Generated Key:

openssl req -new -x509 -key blah.key.pem -out blah.crt.pem

Use only when you’ve no CA and will only be generating one key/certificate (useless for anything that requires signed certificates on both ends)