Cheatsheets - openssl
How to generate a cert?
# generate a private key foo.key of 2048-bit
# => foo.key (public/private key pair)
$ openssl genrsa -out foo.key 2048
# show content of the private key
$ openssl rsa -text -in foo.key -noout
# extract public key (the private key file contains both the private key and the public key).
# foo.key => foo_public.key
$ openssl rsa -in foo.key -pubout -out foo_public.key
# create a certificate signing request (CSR); public key will be included.
# foo.key => foo.csr
$ openssl req -new -key foo.key -out foo.csr
# verify csr
$ openssl req -text -in foo.csr -noout -verify
# option 1: send csr to CA and get the cert; CA signs the cert with their own private key.
# foo.csr => (CA) => foo.crt
# option 2: create a self-signed cert
# foo.key + foo.csr => foo.crt
$ openssl x509 -req -days 365 -in foo.csr -signkey foo.key -out foo.crt
# option 3: create your CA, then create the cert
$ openssl req -x509 -days 365 -newkey rsa:4096 -sha256 -nodes -out ca.crt -keyout ca.key -outform PEM
$ openssl x509 -req -days 365 -in foo.csr -CA ca.crt -CAkey ca.key -out foo.crt
# view cert
$ openssl x509 -text -in foo.crt -noout
# check the purposes of the cert
$ openssl x509 -purpose -in foo.crt -inform PEM
Generate a hash of each file's public key, they should match:
$ openssl pkey -pubout -in foo.key | openssl sha256
$ openssl req -pubkey -in foo.csr -noout | openssl sha256
$ openssl x509 -pubkey -in foo.crt -noout | openssl sha256
How to Verify?
Check content of the cert
# Parse a cert from a file
$ openssl x509 -in /path/to/cert -text -noout
# Parse a cert from a k8s secret
$ kubectl get secret mysecret -n foo-system -o jsonpath='{.data.ca-cert}' | base64 -d | openssl x509 -noout -text
# Extract the public key from root.crt.
$ openssl x509 -in root.crt -noout -pubkey > root.key
-in
filename-text
print out full detailed-issuer
print the issuer name-noout
do not print anything NOT specified
Verify a cert using CA cert
$ openssl verify -CAfile ca.crt foo.crt
Verify if a certificate is self-signed
Check if the subject
and the issuer
are the same entity.
$ openssl x509 -in foo.crt -noout -subject -issuer
Verify if is CA
Check if CA:TRUE
is included in the X509v3 Basic Constraints
.
$ openssl x509 -in foo.crt -noout -text | grep "CA:TRUE"
Or verify by cert-manager. If you are issuing a certificate using cert-manager, and the issuer only has the SelfSigned stanza in the spec
(selfSigned: {}
), then you are using an arbitrary CA.
Verify Keypair
To verify that a private key corresponds to the public key from a certificate or a CSR, print out their modulus and compare the resulting hash-values.
For an ECDSA key pair/certificate:
$ openssl req -in ${CSR_FILE} -noout -pubkey | openssl dgst -sha256
$ openssl ec -in ${KEY_FILE} -pubout | openssl dgst -sha256
$ openssl x509 -in ${CERT_FILE} -noout -pubkey | openssl dgst -sha256
For a RSA key pair/certificate:
$ openssl req -noout -modulus -in ${CSR_FILE} | openssl sha256
$ openssl rsa -noout -modulus -in ${KEY_FILE} | openssl sha256
$ openssl x509 -noout -modulus -in ${CERT_FILE} | openssl sha256
How to check exponents and modulus?
$ openssl rsa -in foo.key -pubout -noout -text
The result looks like this:
modulus: ...
publicExponent: 65537 (0x10001)
privateExponent: ...
prime1: ...
prime2: ...
exponent1: ...
exponent2: ...
coefficient: ...
Note that publicExponent is almost always 65537
(0x10001
).
Check Kubernetes Certs
Kubernetes stores config files in /etc/kubernetes
, to check the cert content (e.g. of the kube-scheduler
):
$ cat /etc/kubernetes/scheduler.conf | yq .users[].user.client-certificate-data | base64 -d | openssl x509 -text
# Result:
Issuer: CN = kubernetes
...
Subject: CN = system:kube-scheduler
Conversions
By default, OpenSSL generates keys and CSRs using the PEM format.
Between PEM and PKCS#12:
# PEM to PKCS#12
$ openssl pkcs12 -export -name "foo-digicert-(expiration date)" \
-out foo.pfx -inkey foo.key -in foo.crt
# PKCS#12 to PEM; PKCS#12 format contains both the certificate and private key
# extract private key
$ openssl pkcs12 -in foo.pfx -nocerts -out foo.key -nodes
# extract cert
$ openssl pkcs12 -in foo.pfx -nokeys -clcerts -out foo.crt
Between PEM and DER: The DER format uses ASN.1
encoding to store certificate or key information. Similar to the PEM format, DER stores key and certificate information in two separate files. The file extension .der
was used in the below examples for clarity.
# convert a PEM encoded certificate into a DER encoded certificate:
$ openssl x509 -inform PEM -in foo.crt -outform DER -out foo.der
# convert a PEM encoded private key into a DER encoded private key:
$ openssl rsa -inform PEM -in foo.key -outform DER -out foo_key.der
# convert a DER encoded certificate into a PEM encoded certificate:
$ openssl x509 -inform DER -in foo.der -outform PEM -out foo.crt
# convert a DER encoded private key into a PEM encoded private key:
$ openssl rsa -inform DER -in foo_key.der -outform PEM -out foo.key
# Check a PEM certificate (`.crt` or `.pem`)
$ openssl x509 -text -noout -in cert.pem
# Check a Certificate Signing Request (CSR)
$ openssl req -text -noout -verify -in CSR.csr
# Check a private key
$ openssl rsa -check -in cert.key
$ cat << EOF > csr.cnf
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[req_distinguished_name]
CN = example.com
[v3_req]
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = example.com
DNS.2 = www.example.com
EOF
openssl req -newkey rsa:2048 -out csr.pem -keyout key.pem -config csr.cnf
openssl config
Config file: /etc/ssl/openssl.cnf
Also:
$ openssl version -d
OPENSSLDIR: "/usr/lib/ssl"
How to generate random strings:
$ openssl rand -base64 10
129udXpYaQJZeg==
How to test a TLS connection?
Check if an endpoint you are connecting to or listening at uses TLS by running the following command:
$ openssl s_client -connect HOST:PORT
# e.g.
$ openssl s_client -connect google.com:443 -showcerts < /dev/null
It shows Certificate chain, server certificate, etc.
The s_client
command implements a generic SSL/TLS client which connects to a remote host using SSL/TLS.
How to check the details of a server cert?
openssl s_client
result can be directly sent to openssel x509
:
$ openssl s_client -connect google.com:443 | openssl x509 -text -noout
What is -showcerts flag?
The showcerts
flag appended onto the openssl s_client connect
command shows the entire certificate chain in PEM format; without -showcerts
flag, it shows only the end entity certificate.
Why openssl s_client does not terminate?
This is because OpenSSL is still connected to the server and waiting for further commands. You can add < /dev/null
to terminate it.
OpenSSL vs BoringSSL
BoringSSL is a much lighter-weight version of OpenSSL with no guarantees of API or ABI stability since Google requires far less legacy application support.
Private key
$ openssl genrsa -out foo.key 4096
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
Private key => Certificate
$ openssl req -x509 -new -nodes -sha512 -days 3650 \
-subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=yourdomain.com" \
-key foo.key \
-out foo.crt
Generated cert:
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----