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:
- Root CA certifaces
- 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:
- This issue for rustls-native-certs
- This issue for golang
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