OpenSSL Pocket Reference
Introduction
As per the Github page of the OpenSSL library, the openssl
command line tool can be used for:
- creation of keys and key parameters
- creation of X.509 certificates, Certificate Signing Requests (CSRs) and Certificate Revocation Lists (CRLs)
- calculation of message digests
- encryption and decryption with the supported ciphers.
- SSL/TLS client and server tests
- many others…
The OpenSSL package can also be used as a C library and linked against.
Glossary of terms used later in this article
- SSL/TLS: Secure Sockets Layer / Transport Layer Security: They are cryptographic protocols designed to provide communications security over a computer network. TLS replaced SSL in recent years.
- Hash Function: Also called CHF (Cryptographic Hash Function) or Message Digests. It maps data of arbitrary size to a bit array of a fixed size (the resulting hash value). It is a one-way function and it must be impossible to invert it. Examples: MD5, SHA1, Whirlpool. It protects only the message’s Integrity.
- MAC: Message Authentication Code: Also known as a tag or a keyed hash, it is used to authenticate a message (certify that the message comes from the stated sender). It hashes the data + a shared secret. It provides Integrity and Authenticity (but does not provide Non-repudiation).
- HMAC: Hash-based Message Authentication Code (MAC): It is a method of turning a Hashing algorithm like MD5 or SHA256 into a MAC, calling them HMAC-MD5 or HMAC-SHA256 respectively.
- Digital Signature: It is created with a private key, and verified with the corresponding public key of an asymmetric key pair. Only the holder of the private key can create this signature, and normally anyone knowing the public key can verify it. So, it provides: Integrity, Authenticity and Non-repudiation.
- CA: Certificate Authority: It is an entity that issues digital certificates. A digital certificate certifies the ownership of a public key by the named subject of the certificate. This allows others to rely upon signatures or on assertions made about the private key that corresponds to the certified public key. A CA acts as a trusted third party—trusted both by the subject (owner) of the certificate and by the party relying upon the certificate.
- PEM: Privacy-Enhanced Electronic Mail: Base64 encoded DER certificate, enclosed between “—–BEGIN CERTIFICATE—–” and “—–END CERTIFICATE—–”. PEM format can also be used to store keys.
- X.509: It is a standard defining the format of public key certificates. An X.509 certificate contains a public key and an identity (a hostname, or an organization, or an individual), and is either signed by a CA or self-signed.
- CSR: Certificate Signing Request - It is a block of encoded text that is given to a Certificate Authority (CA) when applying for an SSL Certificate. It is usually generated on the server where the certificate will be installed and contains information that will be included in the certificate such as the Organization Name, Domain Name, City, and Country.
- PKI: Public-Key Infrastructure: A public key infrastructure (PKI) is a set of roles, policies, hardware, software and procedures needed to create, manage, distribute, use, store and revoke digital certificates and manage public-key encryption. It binds public keys with respective identities of entities (like people and organizations).
Obtaining basic information about OpenSSL
$ openssl version -a
OpenSSL 1.1.1f 31 Mar 2020
built on: Wed Feb 17 12:35:54 2021 UTC
platform: debian-amd64
options: bn(64,64) rc4(16x,int) des(int) blowfish(ptr)
compiler: gcc -fPIC -pthread -m64 -Wa,--noexecstack -Wall -Wa,--noexecstack -g -O2 -fdebug-prefix-map=/build/openssl-g4Ey0B/openssl-1.1.1f=. -fstack-protector-strong -Wformat -Werror=format-security -DOPENSSL_TLS_SECURITY_LEVEL=2 -DOPENSSL_USE_NODELETE -DL_ENDIAN -DOPENSSL_PIC -DOPENSSL_CPUID_OBJ -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DKECCAK1600_ASM -DRC4_ASM -DMD5_ASM -DAESNI_ASM -DVPAES_ASM -DGHASH_ASM -DECP_NISTZ256_ASM -DX25519_ASM -DPOLY1305_ASM -DNDEBUG -Wdate-time -D_FORTIFY_SOURCE=2
OPENSSLDIR: "/usr/lib/ssl"
ENGINESDIR: "/usr/lib/x86_64-linux-gnu/engines-1.1"
Seeding source: os-specific
The most interesting configs here are the build date and the folder where OpenSSL keeps its configuration: OPENSSLDIR.
Getting the available commands:
$ openssl help
Standard commands
asn1parse ca ciphers cms
crl crl2pkcs7 dgst dhparam
dsa dsaparam ec ecparam
enc engine errstr gendsa
genpkey genrsa help list
nseq ocsp passwd pkcs12
pkcs7 pkcs8 pkey pkeyparam
pkeyutl prime rand rehash
req rsa rsautl s_client
s_server s_time sess_id smime
speed spkac srp storeutl
ts verify version x509
Message Digest commands (see the 'dgst' command for more details)
blake2b512 blake2s256 gost md4
md5 rmd160 sha1 sha224
sha256 sha3-224 sha3-256 sha3-384
sha3-512 sha384 sha512 sha512-224
sha512-256 shake128 shake256 sm3
Cipher commands (see the 'enc' command for more details)
aes-128-cbc aes-128-ecb aes-192-cbc aes-192-ecb
aes-256-cbc aes-256-ecb aria-128-cbc aria-128-cfb
aria-128-cfb1 aria-128-cfb8 aria-128-ctr aria-128-ecb
aria-128-ofb aria-192-cbc aria-192-cfb aria-192-cfb1
aria-192-cfb8 aria-192-ctr aria-192-ecb aria-192-ofb
aria-256-cbc aria-256-cfb aria-256-cfb1 aria-256-cfb8
aria-256-ctr aria-256-ecb aria-256-ofb base64
bf bf-cbc bf-cfb bf-ecb
bf-ofb camellia-128-cbc camellia-128-ecb camellia-192-cbc
camellia-192-ecb camellia-256-cbc camellia-256-ecb cast
cast-cbc cast5-cbc cast5-cfb cast5-ecb
cast5-ofb des des-cbc des-cfb
des-ecb des-ede des-ede-cbc des-ede-cfb
des-ede-ofb des-ede3 des-ede3-cbc des-ede3-cfb
des-ede3-ofb des-ofb des3 desx
rc2 rc2-40-cbc rc2-64-cbc rc2-cbc
rc2-cfb rc2-ecb rc2-ofb rc4
rc4-40 seed seed-cbc seed-cfb
seed-ecb seed-ofb sm4-cbc sm4-cfb
sm4-ctr sm4-ecb sm4-ofb
# Your output may differ depending on the OpenSSL version.
# Getting available digests
$ openssl dgst -list
$ openssl dgst -help
# Getting available ciphers
$ openssl enc -list
$ openssl enc -help
Generating pseudo-random numbers with OpenSSL
$ openssl rand -help
Valid options are:
-help Display this summary
-out outfile Output file
-rand val Load the file(s) into the random number generator
-writerand outfile Write random data to the specified file
-base64 Base64 encode output
-hex Hex encode output
-engine val Use engine, possibly a hardware device
# Generate 32 bytes of random data in hex format (64 hex characters) - write to stdout
$ openssl rand -hex 32
e332d8bde28abd882a879f89824a315d31c8f8e6c440ed010c306ea4be82857b
# Generate 32 bytes of random data in base64 format - write to stdout
$ openssl rand -base64 32
g8mPm313yRS9Klwo73cKgDbjggS7m4/uTabddrFsufU=
$ openssl rand -base64 32 | base64 --decode
Generating keys with OpenSSL
# Generate a 2048-bit RSA private key encoded with aes128 in PEM format
$ openssl genrsa -aes128 -out my.key 2048
# Output RSA key details
$ openssl rsa -text -in my.key
# Extract just the public key from the RSA key
$ openssl rsa -in specflare.key -pubout -out specflare-public.key
# Extract just the private key from the RSA key
$ openssl rsa -in specflare.key -out specflare-private.key
# Verify a private key
$ openssl rsa -in specflare-private.key -check
# Generate a 2048-bit DSA key encrypted with aes128
$ openssl dsaparam -genkey 2048 | openssl dsa -out dsa.key -aes128
# Generate ECDSA (Elliptic Curve DSA) key with a fixed key size (controlled by the chosen elliptic curve)
$ openssl ecparam -genkey -name secp256r1 | openssl ec -out ec.key -aes128
# Get list of ECs
$ openssl ecparam -list_curves
Generating a CSR (Certificate Signing Request) with OpenSSL
This is a formal request asking a CA to sign a certificate, and it contains the public key of the entity requesting the certificate and some information about the entity. This data will all be part of the certificate. A CSR is always signed with the private key corresponding to the public key it carries.
$ openssl req -help
$ openssl genrsa -aes128 -out specflare.key 2048
$ openssl req -new -key specflare.key -out specflare.csr
# Check if the CSR is correct:
$ openssl req -text -in specflare.csr -noout
Certificate Request:
Data:
Version: 1 (0x0)
Subject: C = RO, ST = Romania, L = Bucharest, O = Specflare, OU = Software, CN = specflare.com, emailAddress = liviu@specflare.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus: (... omitted bulk of data ...)
Exponent: 65537 (0x10001)
Attributes:
a0:00
Signature Algorithm: sha256WithRSAEncryption
(... omitted bulk of data ...)
# Verify CSR
$ openssl req -text -noout -verify -in specflare.csr
Generating CSRs from existing certificates - for certificate renewal
If you’re renewing an old certificate and don’t want to make any changes to the information present in it, you can just do:
$ openssl x509 -x509toreq -in specflare.crt -out specflare.csr -signkey specflare.key
You can use either the old key or generate a new one and use it (better).
Generating a self-signed certificate from your own CSR
If you don’t want to pay for a CA-signed certificate, you can generate your own self-signed certificate. Please note that using it in your web server for instance, will warn your clients that your site uses a self-signed certificate.
# Generate a self-signed certificate valid for 3 years (1095 days) using given key and CSR
$ openssl x509 -req -days 1095 -in specflare.csr -signkey specflare.key -out specflare.crt
# Generating a self-signed certificate in a single step (CSR + Cert)
$ openssl req -new -x509 -days 1095 -key specflare.key -out specflare.crt
# Generate a self-signed certificate in one command (without being asked about entity info)
$ openssl req -new -x509 -days 365 -key specflare.key -out specflare.crt -subj "/C=RO/L=Bucharest/O=Specflare/CN=www.specflare.com"
# See the generated certificate
$ openssl x509 -text -in specflare.crt -noout
# Checking if the modulus match for the private key, CSR and certificate
$ openssl x509 -noout -modulus -in specflare.crt | openssl md5
$ openssl rsa -noout -modulus -in specflare.key | openssl md5
$ openssl req -noout -modulus -in specflare.csr | openssl md5
Converting a certificate (or key) from one form to another
The most common formats are DER (raw binary formatm using DER ASN.1 encoding) and PEM (base64 encoded DER).
# Convert certificates from PEM to DER and vice-versa
$ openssl x509 -inform PEM -in specflare.pem -outform DER -out specflare.der
$ openssl x509 -inform DER -in specflare.der -outform PEM -out specflare.pem
# Convert RSA or DSA keys from PEM to DER and vice-versa
$ openssl rsa -inform PEM -in specflare.key -outform DER -out specflare.key.der
$ openssl dsa -inform DER -in specflare.key.der -outform PEM -out specflare.key.pem
Understanding cipher suites
In SSL and TLS, cipher suites define how secure communication takes place. TLS clients submit a list of cipher suites that they support, and servers choose one suite from the list to use for the connection. Both client and server must support the selected suite.
$ openssl ciphers -v
RSA-PSK-AES256-CBC-SHA384 TLSv1 Kx=RSAPSK Au=RSA Enc=AES(256) Mac=SHA384
# (... multiple lines omitted ...)
Each cipher suite line contains the following information:
- Cipher suite name, in our case
RSA-PSK-AES256-CBC-SHA384
- Minimum protocol version that supports this cipher suite:
TLSv1
- Key exchange algorithm:
Kx=RSAPSK
- Authentication algorithm:
Au=RSA
- Cipher algorithm and block size:
Enc=AES(256)
- MAC (Message Authentication Code) algorithm:
Mac=SHA384
You can use different selection strings for the cipher suite to tune your selection:
# Returns only cipher suites containing AES256
$ openssl ciphers -v 'AES256'
$ openssl ciphers -v 'ALL'
# All OpenSSL ciphers including NULL ciphers:
$ openssl ciphers -v 'ALL:eNULL'
# All RC4 ciphers skipping those without authentication:
$ openssl ciphers -v 'RC4:!COMPLEMENTOFDEFAULT'
The cipher suite selection string is well explained here.
Connecting to a TLS-secured host with OpenSSL
$ openssl s_client -help
$ openssl s_client -connect www.specflare.com:443
# Connecting by specifying the CA certificates (this path may be different on other OSes: /etc/ssl/certs/)
$ openssl s_client -connect www.specflare.com:443 -CAfile /etc/ssl/certs/ca-certificates.crt
You can try to connect to a TLS-secured host using only a small list of supported ciphers (from the client-side), by providing a cipher configuration string. You can even get the list of supported ciphers by the other party if you send successive requests with every cipher from the client side, and see which are supported and which are not.
$ openssl s_client -connect www.specflare.com:443 -cipher SHA1
Leave a comment