OpenSSL basics

Make secure web traffic a reality with OpenSSL

view on github

OpenSSL

✔️ OpenSSL is used to secure web traffic.

✔️ OpenSSL contains an open-source implementation of the SSL and TLS protocols used to add an encryption layer on top of TCP sockets during HTTP client/server sessions (HTTPS).

✔️ The core library, written in the C programming language, implements basic cryptographic functions and provides various utility functions.

General commands / algorithms lists

# detailed man pages on openssl commands
man -k openssl

# help on any command/digest/algo/method etc use
openssl <anything> -help

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

# digests commands (produce fixed-length hashes from any input)
openssl list -digest-commands

# cipher commands (provide encryption using symmetric ciphers)
openssl list -cipher-commands

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

# public key algorithms (provide asymmetric encrypytion using key pairs)
openssl list -public-key-algorithms

# 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

Configuration files and directories

# OpenSSL configuration options, man page
/etc/ssl/openssl.cnf
man openssl

# symlinks to CA (certification authorities) certificates directory
/etc/ssl/certs/.

# installed CA certificates directory
/usr/share/ca-certificates/mozilla/.
# hashes <input-file> using <digest-command> algorithm and writes output to <digest-file>
openssl <digest-command> -out <digest-file> <input-file>

# hashes <input-file> using default digest algorithm and writes output to stdout
openssl dgst <input-file>
# encrypts <some-text> using <cipher>, prompts for passphrase, writes to <encrypted-file>
echo <some-text> | openssl enc -e -<cipher> -out <encrypted-file>

# prompts for passphrase, decrypts <encrypted-file> to stdout (<cipher> used for encryption has to be known)  
openssl enc -d -<cipher> -in <encrypted-file>

# symmetric encryption of <plain-file> using <cipher-command> cipher, protect with <password>, encode output in base64 and write to <encrypted-file>
openssl <cipher-command> -in <plain-file> -out <encrypted-file> -e -a -v -pass pass:<password>

# read base64 input from <encrypted-file>, provide passphrase <password>, decrypt to <decrypted-file> using <cipher-command> cipher
openssl <cipher-command> -in <encrypted-file> -out <decrypted-file> -d -a -v -pass pass:<password>

✔️ OpenSSL supports the following algorithms for private key generation :

  1. RSA
  2. RSA-PSS
  3. EC
  4. X25519
  5. X448
  6. ED25519
  7. ED448
# help on how to generate/manage/use key pairs
man genpkey
man pkey
man pkeyutl

# checks if <file> is a valid private key
openssl pkey -in <file> -check -noout

# prints cryptographic details (modulus, primes, etc ...) for <private-key-file> 
openssl pkey -in <private-key-file> -text -noout

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

# 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-file>
openssl genpkey -<cipher> -pass pass:<password> -out <private-key-file> -outform PEM -algorithm RSA -pkeyopt rsa_keygen_bits:<bits>

# creates the public key for <private-key-file> in .pem format, writes it to <public-key-file>
openssl pkey -in <private-key-file> -out <public-key-file> -pubout -outform PEM

# encrypts <some-text> using public key <public-key-file>, writes to <encrypted-file>
echo <some-text> | openssl pkeyutl -encrypt -pubin -inkey <public-key-file> -out <encrypted-file>

# decrypts <encrypted-file> using private key <private-key-file>
openssl pkeyutl -in <encrypted-file> -decrypt -inkey <private-key-file>

# the following method is used to perform authentication during Diffie Hellman key exchange (using a RSA key pair)

# hashes <input-file> using <digest-command>, signs the hash using <private-key-file> and writes the result to <signed-hash-file> using default pkcs padding
openssl <digest-command> <input-file> | openssl rsautl -sign -inkey <private-key-file> -out <signed-hash-file> -pkcs

# produces signature file using pkeyutl instead of rsautl: fails when using SHA-256 digest, while the rsautl version works ?
# openssl <digest-command> <input-file> | openssl pkeyutl -sign -inkey <private-key-file> -out <signed-hash-file> -pkeyopt rsa_padding_mode:pkcs1

# verifies that <signed-hash-file> was signed using the private key matching <public-key-file> and outputs the original hash to stdout
openssl rsautl -verify -in <signed-hash-file> -pubin -inkey <public-key-file>

# it can be used as well to authentify a file by comparing the signed hash value with the hash value of the file to authentify
# if the hashes match, the file is sucessfully authentified as having been hashed, then signed by the owner of the private key
# creates CSR for <private-key-file> in .pem format, writes it to <csr-file> (combine with -x509 option to immediately create a self-signed certificate)
openssl req -key <private-key-file> -new -outform PEM -out <csr-file> -verbose

# outputs request summary for <csr-file>
openssl req -in <csr-file> -subject -noout

# prints certificate in ASCII
openssl storeutl -certs <certificate>

# prints certificate details
openssl x509 -in <certificate> -noout -text

# creates a self-signed certificate: signs <csr-file> with .pem private key <private-key-file> from which it was created
# then issues a certificate that will be valid for <days> days and writes it to <crt-file>
openssl x509 -req -in <csr-file> -keyform PEM -signkey <private-key-file> -out <crt-file> -days <days>

OpenSSL and TLS v1.2 key exchange

# uses 2048 bits RSA / P-256 ECDSA certificate

# create PKCS#3 DH parameters in .pem format using a <bits> length prime, writes it to <dh-params-file> - use for DH key exchange
openssl genpkey -genparam -algorithm DH -pkeyopt dh_paramgen_prime_len:<bits> -pkeyopt dh_paramgen_type:0 -outform PEM -out <dh-params-file>

# create ED25519 private key (public key algorithm using x25519 curve), writes it to <private-key-file>
# ED25519 can be used for authentication (in suite ECDHE-ECDSA-AES128-GCM-SHA256 in place of ECDSA for instance)
# but since it does not appear in SSL/TLS specifications browsers will not support it ...
openssl genpkey -out <private-key-file> -outform PEM -algorithm ED25519

OpenSSL and TLS v1.3 key exchange

# uses P-256 ECDSA certificate

# list all supported curves for EC cryptography 
# the named curve to use for ECDH key agreement has to be indicated to the web server
# it is independant of the named curve/parameters used to generate ECDSA key pairs
openssl ecparam -list_curves

# generates an unencrypted EC private key using <elliptic-curve> in .pem format, writes it to <private-key-file> - use for ECDSA authentication
openssl ecparam -param_enc named_curve -name <elliptic-curve> -genkey -noout -outform PEM -out <private-key-file>

# creates the public key for <private-key-file> in .pem format, writes it to <public-key-file>
# EC key pairs can also be used for asymmetric encryption (and they're shorter than RSA keys)
openssl ec -in <private-key-file> -inform PEM -pubout -outform PEM -out <public-key-file>

Other utilities

# will open a SSL/TLS connection and output information about certificate, authentication, key agreement, etc ...
openssl s_client -connect <host>:<port>