OpenSSL basics

Make secure web traffic a reality with OpenSSL

view on github

OpenSSL

  • openssl is a cryptographic framework that implements several cryptographic primitives (as in openssh and gpg).
  • However, openssl is the most comprehensive of them all due to the variety of algorithms and use cases it supports.
  • Some of its use cases are assets encryption and verification, network traffic encryption and identities management.

Table of contents

  1. Overview
  2. Commands
  3. Use cases for public key cryptography
  4. Other utilities

Overview

Help features

# general man page
man openssl

# general commands (key pairs, certificate examination, etc)
openssl list -commands

# detailed man pages on available commands
man -k openssl | less

# help on any command/digest/algo/method etc
openssl "$something" -help

Configuration

# print configuration file
cat /etc/ssl/openssl.cnf

# print symlinks to CA certificates
ls -la /etc/ssl/certs/.

# print installed CA certificates
ls -la /usr/share/ca-certificates/mozilla/.

# details on certificates management (installed vs trusted)
man update-ca-certificates

Commands

Digests

  • Digests produce fixed-length hashes from any input :
# help on how to use digest commands
man openssl-dgst

# hashes $file using default algorithm, writes to stdout
openssl dgst "$file"

# for every digest available, there is a command of the same name
openssl list -digest-commands

# supported algorithms list
openssl list -digest-algorithms

# hashes $file using algorithm $digest, writes to $file_hash
openssl "$digest" -out "$file_hash" "$file"

Ciphers

# help on how to use cipher commands
man openssl-enc

# for every cipher available, there is a command of the same name
openssl list -cipher-commands

# supported algorithms list
openssl list -cipher-algorithms

# encrypts $some_text using $cipher, prompts for password, writes to $encrypted_file
echo "$some_text" | openssl enc -e "-$cipher" -pbkdf2 -out "$encrypted_file"

# prompts for password, uses $cipher to decrypt $encrypted_file to stdout
openssl enc -d "-$cipher" -pbkdf2 -in "$encrypted_file"

# encrypt $file using $cipher, protect with $password, encode output to base64, writes to $encrypted_file
openssl "$cipher" -in "$file" -e -a -pass "pass:$password" -out "$encrypted_file"

# decrypts base64 input from $encrypted_file using $cipher, provide passphrase $password, writes to $file
openssl "$cipher" -in "$encrypted_file" -d -a -pass "pass:$password" -out "$file"

Public key

# help on how to use public key commands (generate, manage and use key pairs)
man openssl-genpkey
man openssl-pkey
man openssl-pkeyutl

# supported public key algorithms list
openssl list -public-key-algorithms

# checks if $private_key contains a valid private key
openssl pkey -in "$private_key" -check -noout

# prints cryptographic details (modulus, primes, etc ...) for $private_key
openssl pkey -in "$private_key" -text -noout

# generates an unencrypted RSA private key of $bits length in .pem format, writes it to $private_key
openssl genpkey -algorithm RSA -pkeyopt "rsa_keygen_bits:$bits" -outform PEM -out "$private_key"

# in order to be password protected, a private key has to be ciphered ...

# generates a $cipher encrypted RSA private key of $bits length in .pem format, protected by $password, writes it to $private_key
openssl genpkey -algorithm RSA -pkeyopt "rsa_keygen_bits:$bits" -outform PEM "-$cipher" -pass "pass:$password" -out "$private_key"

# generates the public key for $private_key in .pem format, writes to $public_key
openssl pkey -in "$private_key" -pubout -outform PEM -out "$public_key.pub"

# encrypts $file with $public_key, writes to $encrypted_file
openssl pkeyutl -in "$file" -encrypt -inkey "$public_key.pub" -pubin -out "$encrypted_file"

# decrypts $encrypted_file with $private_key, writes to stdout
openssl pkeyutl -in "$encrypted_file" -decrypt -inkey "$private_key"
  • Supported public key algorithms are RSA, RSA-PSS, EC, X25519, X448, ED25519 and ED448
  • However, RSA and EC are the most widely used and the most reliable.

Use cases for public key cryptography

  • Digital signatures are used to authenticate files.
  • Digital signatures are similar to but different from message authentication codes.
  • Sender hashes a file and signs it with their private key to produce a signature (signed hash).
  • Receiver hashes the file to authenticate and verify it against the signature with sender's public key.
  • If hashes match, verification succeeds and the file is authenticated as having been hashed and signed by the private key owner.
# binary hashes $file using algorithm $digest, writes to $file_hash
openssl "$digest" -binary -out "$file_hash" "$file"

# signs the hash with $private_key, writes to $signed_hash using pkcs padding
openssl pkeyutl -in "$file_hash" -sign -inkey "$private_key" -pkeyopt "rsa_padding_mode:pkcs1" -out "$signed_hash"

# verifies that $signed_hash matches $hash and was signed with $private_key
openssl pkeyutl -in "$file_hash" -verify -inkey "$public_key.pub" -pubin -sigfile "$signed_hash"

# recover the original hash from the signature file
openssl pkeyutl -in "$signed_hash" -verifyrecover -inkey "$public_key.pub" -pubin
  • PKI is used to authenticate identities through a trusted third party.
  • openssl can create *.crt x509 certificates as well as *.csr certificate signing requests from private keys.
  • Certificate authority : provision a CA with a private key and self signed certificate.
  • Create x509 certificate signing requests from private keys of identities to authenticate.
  • Registration authority : issue certificates for identities by signing the requests with the CA private key.
  • Validation authority : an entity authenticates another entity if it trusts its certificate's issuer (CA).
# root subject
ca_subj="/C=FR/O=Acme/CN=root/emailAddress=root@acme.com"
# creates a self-signed certificate to use as a root CA :
# pass $ca_private_key and $subj, valid for $days, writes in *.pem format to $ca_certificate
openssl req -new -key "$ca_private_key" -x509 -subj "$ca_subj" -days "$days" -outform PEM -out "$ca_certificate.crt"

# entity subject
subj="/C=FR/O=Acme/OU=users/CN=user/emailAddress=user@acme.com"
# creates certificate signing request for $private_key in .pem format, writes to $sign_request
openssl req -new -key "$private_key" -subj "$subj" -outform PEM -out "$sign_request.csr"

# prints request summary for $sign_request
openssl req -in "$sign_request.csr" -noout -subject

# creates certificate from signing request, pass root CA key and certificate, valid for $days, digest algorithm, writes in *.pem format to $certificate
openssl x509 -req -in "$sign_request.csr" -CA "$ca_certificate.crt" -CAkey "$ca_private_key" -days "$days" -sha256 -outform PEM -out "$certificate.crt"

# use $ca_certificate to verify that $certificate was issued by the root CA
openssl verify -CAfile "$ca_certificate.crt" "$certificate.crt"

# prints certificate details
openssl x509 -in "$certificate.crt" -noout -text

# prints certificate in ASCII
openssl storeutl -certs "$certificate.crt"
  • TLS is used for securing web traffic through HTTPS.
  • openssl can create EC as well as RSA private keys for TLS v1.2 and v1.3.
  • EC key pairs can also be used for asymmetric encryption (and they're shorter than RSA keys).
  • openssl supports ED25519 keys as well (they can be used for SSH authentication but are not supported in TLS).
# supported key exchange methods (TLS support - includes RSA and DH)
openssl list -public-key-methods

# lists all available cipher suites for key exchange
openssl ciphers -stdname | sort | column -tN SUITE\ \(STANDARD\ NAME\),-,SUITE,PROTO,KEY_EXCHANGE,AUTH,SESSION,DIGEST | less

# TLS v1.2 cipher suite DHE-RSA-AES128-GCM-SHA256 requires :
# 1. 2048 bits RSA key and certificate for authentication (see above)
# 2. 2048 bits DH parameters for DH key exchange

# create PKCS#3 DH parameters in .pem format using a 2048 bits prime, writes it to $dh_params
openssl genpkey -genparam -algorithm DH -pkeyopt "dh_paramgen_prime_len:2048" -pkeyopt "dh_paramgen_type:0" -outform PEM -out "$dh_params"

# TLS v1.3 cipher suite TLS_AES_128_GCM_SHA256 requires :
# 1. ECDSA key and certificate for authentication

# list all supported curves for EC cryptography
openssl ecparam -list_curves

# uses curve P-256 to create an unencrypted EC private key in .pem format, writes to $private_key
openssl genpkey -algorithm EC -pkeyopt "ec_param_enc:named_curve" -pkeyopt "ec_paramgen_curve:prime256v1" -outform PEM -out "$private_key"

# create ED25519 private key (public key algorithm using x25519 curve), writes to $private_key
openssl genpkey -algorithm ED25519 -outform PEM -out "$private_key"

Other utilities

# opens a SSL/TLS connection and output information about certificate, authentication, key agreement, etc ...
openssl s_client -connect "$host:$port"