OpenSSL basics
Make secure web traffic a reality with OpenSSL

-
openssl
is a cryptographic framework that implements several cryptographic primitives (as inopenssh
andgpg
). - 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.
# 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
# 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
- 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 provide symmetric encryption capabilities :
# 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 commands provide asymmetric encryption capabilities :
# 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
andED448
- However,
RSA
andEC
are the most widely used and the most reliable.
- 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 key exchange
- TLS is used for securing web traffic through HTTPS.
-
openssl
can createEC
as well asRSA
private keys for TLS v1.2 and v1.3. -
EC
key pairs can also be used for asymmetric encryption (and they're shorter thanRSA
keys). -
openssl
supportsED25519
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"
# opens a SSL/TLS connection and output information about certificate, authentication, key agreement, etc ...
openssl s_client -connect "$host:$port"