OpenSSL commands
Here’s my notes of openssl
commands for remembering (my own copy-pasting). There are other crypto/ssl/tls tools available (e.g., step, cfssl, certstrap etc) but openssl
are the most widely used, at least that I know of.
If you don’t know what SSL/TLS/HTTPS is, or just want to learn more about it make sure to check out Julia Evans: What’s TLS and DNSimple’s comic: How HTTPS works. Both awesome resources!
Create RSA key pair in PEM
When creating keys to test and dev environments. Size can be 1024
, 2048
, 4096
NOTE: Private key in PKCS1
and public key in SPKI
format
openssl genrsa -out private.pem 2048 && openssl rsa -in private.pem -outform PEM -pubout -out public.pem
Create signature
Creates a base64 encoded signature. The default algorithm used is RSASSA-PKCS1-v1_5
and we’re setting SHA-256
as hash.
NOTE: -n
option is easy to miss (it removes a trailing newline)
echo -n "hello world" | openssl dgst -sha256 -sign private.pem | base64
# Example with newlines in message
echo -n "hello\\nworld" | openssl dgst -sha256 -sign private.pem | base64
# Example with data from file.
# BEWARE: Removes trailing newline from `data.txt`
printf %s "$(cat data.txt)" | openssl dgst -sha256 -sign private.pem | base64
# Do not remove trailing newline
cat data.txt | openssl dgst -sha256 -sign private.pem | base64
# From file / to file
openssl dgst -sha256 -sign private.pem -out data.txt.sha256 data.txt
Verify signature
openssl dgst -sha256 -verify public.pem -signature data.txt.sha256 data.txt
Convert PEM to DER and then base64 it
To get rid of newlines and type header. This gives you a base64 key on one line
openssl rsa -pubin -inform PEM -in public.pem -outform DER | base64
Convert PKCS1 key to PKCS8 private key
Web browser crypto supports PKCS8 and openssl
is using PKCS1 as default
openssl pkcs8 -topk8 -inform PEM -outform PEM -in private-pkcs1.pem -out private-pkcs8.pem -nocrypt
Create sha256 hash of public key
Outputs a HEX digest of the binary DER key
TODO: What are the use cases? Why not use fingerprint?
openssl rsa -in public.pem -pubin -outform der | openssl dgst -sha256
# step equivalent
step crypto hash digest <(openssl rsa -in public.pem -pubin -outform der)
Fetch remote x509 cert
This gets all information including the whole certificate chain and doesn’t decode certs
openssl s_client -showcerts -connect bolmaster2.com:443
This shortcut decodes the leaf certificate for you:
echo | openssl s_client -showcerts -connect bolmaster2.com:443 | openssl x509 -noout -text
Decode x509 cert
When you get tired of staring at those base64 characters… Read it like a human instead!
openssl x509 -in cert.pem -noout -text
Inspect/decode keys
Often I want to see more than just base64 mumbo jumbo saying it’s a private or public key, or which program made the output, in the header.
openssl asn1parse -in key.pem
Here is a javascript website doing it: http://lapo.it/asn1js/
Create self signed certificate
Creates a key and certificate it for localhost
. Includes subjectAltName
as well.
openssl req -x509 -out localhost.crt -keyout localhost.key \
-newkey rsa:2048 -nodes -sha256 \
-subj '/CN=localhost' -extensions EXT -config <( \
printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")
Update macOS keychain to trust it
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain localhost.crt
NOTE: Some applications don’t use the macOS keychain as CA store, they use their own. E.g., openssl, curl (if using openssl), nodejs, firefox etc.
Alternatives
Use minica or mkcert if you want to create a local root certificate and sign other’s with that, then you only need to trust that one root certificate. Which can be a good idea if you want to create multiple certificates.
Create random bytes
openssl
has a built-in PRNG which can easily generate both binary, base64 and hex random output:
# Generating 32 random bytes in different formats
openssl rand 32
openssl rand -hex 32
openssl rand -base64 32
# Replace +/ with AB and remove padding (=) making it base62
openssl rand -base64 32 | tr "+/" "AB" | tr -d =
# Web safe base64
openssl rand -base64 32 | tr "+/" "-_" | tr -d =
Resources
- Comparison of TLS implementations
- Teaching of ASN.1 standard
- Let’s Encrypt: ASN.1 and DER (a more modern description than the above)
- Let’s Encrypt: Certificates for localhost
- Julia Evans on TLS
- How HTTPS works comic by dnsimple