Keys and Certificates

Discover Public Certificates

Use cert.sh. For example, to see all certs issued for cats.com: https://crt.sh/?q=%25.cats.com

Advanced search page: https://crt.sh/?a=1

The data is stored in a relational DB. Optionally show the SQL query a page makes using &showSQL=Y, or by selecting "Show SQL?" on the advanced search page.

Create an SSH Key Pair

ssh-keygen creates two files: $keyname and $keyname.pub.

No Passphrase

For RSA: use -t rsa -b 2048.

ssh-keygen \
    -t ed25519 \
    -N "" \
    -f ~/.ssh/$keyname \
    -C "$email"

The email address is optional:

ssh-keygen -t ed25519 -f ~/.ssh/$keyname -N ""

With Passphrase

ssh-keygen -t ed25519 -f ~/.ssh/$keyname

Conversions

Generate a public key from a private key:

ssh-keygen -y \
           -f ~/.ssh/${keyname}.pem \
           $HOME/.ssh/${keyname}.pub

Eliptic Curve Keys and Certs

List Curves

prime256v1 is suitable for JWT signing (ref).

openssl ecparam -list_curves

Creating Certificates

Using go generatecert

There is a golang tool to create self-signed certs at $(go env GOROOT)/src/crypto/tls/generate_cert.go. Use it like:

go run \
   $(go env GOROOT)/src/crypto/tls/generate_cert.go \
   --host localhost \
   --rsa-bits 2048

Using openssl

The openssl genrsa command creates a private key that includes a public key.

openssl genrsa 1024

Extract the public key from the private key:

echo "$keypair" | openssl rsa -outform PEM -pubout

Using keytool

The Java JDK comes with a command called keytool.

CA Certificates

From RFC 5280:

CA certificates may be further divided into three classes: cross-certificates, self-issued certificates, and self-signed certificates.

Every root CA certificate is a self-signed certificate. Intermediate CA certificates are not self-signed; they are signed by their parent CA.

Self-Issued Certificates

From RFC 5280:

Self-issued certificates are CA certificates in which the issuer and subject are the same entity. Self-issued certificates are generated to support changes in policy or operations.

Self-Signed Certificates

From RFC 5280:

Self-signed certificates are self-issued certificates where the digital signature may be verified by the public key bound into the certificate. Self-signed certificates are used to convey a public key for use to begin certification paths.

That is, self-signed certificates are either:

  1. Root CA certifaces
  2. You're a rogue renegade signing certs like a villian
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes \
        -key ca.key \
        -subj "/CN=${CommonName}" \
        -days 3650 \
        -out ca.crt

Cross-Certificate

From RFC 5280:

Cross-certificates are CA certificates in which the issuer and subject are different entities. Cross-certificates describe a trust relationship between the two CAs.

Entity Certificates

End entity certificates are issued to subjects that are not authorized to issue certificates.

Create a new keypair. This creates two file: client.key (which actually has both the public and private key in it).

openssl genrsa -out client.key 2048

Create a Certificate Signing Request (CSR), which is a document that associates some metadata with the key. This creates one file: client.csr.

openssl req -new \
        -key client.key \
        -subj "/CN=${CommonName}" \
        -out client.csr

Create a client certificate by signing the CSR with the CA's private key. I suppose the CA might first verify that the information in the CSR is consistent (does the requester actually own the Common Name?), but in practice I'm not sure of any examples where that actually happens.

openssl x509 -req \
        -in client.csr \
        -CA $CACertFile \
        -CAkey $CAKeyFile \
        -CAcreateserial \
        -out client.crt \
        -days 3650 \
        -sha256

cfssl

cfssl selfsign www.example.net acm-test.json \
    | cfssljson -bare acm-test

Fingerprint

openssl x509 -noout -fingerprint -sha256 \
        -inform pem -in $file
ssh-keygen -lf $file
ssh-keygen -l -E md5 -f $file

AWS EC2 KeyPairs created by AWS are rather specific. This command is from the docs here about how to check their fingerprint.

openssl pkcs8 -in $file \
        -inform PEM -outform DER -topk8 -nocrypt \
    | openssl sha1 -c

Native Certs

Sometimes certificates are bundled with applications; e.g. browsers bundle a set of certificates curated by the browser's creators.

Other times, certificates are installed on, and managed by, the OS. These are referred to as "native certificates".

Properly using native certificates is a headache, and requires knowledge of how the OS handles certificates. See:

However, if you're not trying to make the perfect system, you can just trust whatever certs are in the MacOS Keychain or use the update-ca-certificates program on Debian.

Fetch remote certificate

openssl s_client -connect $domain:443 -showcerts

Checking and Viewing Certs

View local cert info

Show cert info for a local certificate file.

openssl x509 -in $cert -text -noout

Check if a Private Key Matches a Certificate

On the private key:

openssl rsa -modulus -noout -in $key

On the certificate:

openssl x509 -modulus -noout -in $cert

If the output of those two are the same, then the keys go together. An easy way to compare them is to pipe them both to openssl md5.

CSR

openssl req -text -noout -verify -in $file.csr

Verify Cert with CA

openssl verify -CAfile ca.crt entity.crt

PKCS12

PKCS12 is a format that allows for bundling a private key and its associated certificate (and potentially more) in a single file. PKCS12 is a binary format, so the file contents cannot be viewed without a tool like openssl.

View info

openssl pkcs12 -info -in cert.p12 -nodes