If only everything had a certificate (and relevent certificate authorities), identity would be easy...

Anyway, openssl is still probably the most common tool, but we want shiny new things, right?


mkcert does 2 things: install a local CA, and generate certificates signed by the CA.

# create/install a CA
mkcert -install
# show where the CA key/cert are
mkcert -CAROOT

# create leaf certificate
mkcert -ecdsa


step-cli bundles a lot of certificate / things that need signing tools together. More verbose but also gives more control.

# create root ca
step-cli certificate certificate create $subject root.crt root.key --profile=root-ca --kty OKP --curve Ed25519
# install a ca
step-cli certificate install root.crt

# (optional) create intermediate ca
step-cli certificate certificate create $subject intr.crt intr.key --profile=intermediate-ca --kty OKP --curve Ed25519 --ca root.crt --ca-key root.key
# create leaf certificate
step-cli certificate certificate create $subject leaf.crt leaf.key --profile=leaf --kty OKP --curve Ed25519 --ca intr.crt --ca-key root.key --san --san

# view cert details
step-cli certificate inspect cert.pem

step-cli can also do a lot more stuff, some interesting ones:


cfssl is more geared towards api use, at a minimum, you need to provide a CSR in json for it to generate keys / sign.


cert-manager is a ca thingy you run in k8s. it has a kubectl plugin to help with managing certs, a bit like cfssl, but with yaml.


openssl the sort of inconsistent thing that we're all stuck with.

# create root ca
openssl req -x509 -key <(openssl genpkey -algorithm ED25519 | tee root.key) -subj "/CN=me" -out root.crt

# create leaf cert
openssl x509 -req -in <( \
  openssl req -new -key <( \
    openssl genpkey -algorithm ED25519 | tee leaf.key \
  ) -subj "/CN=me" \
) -CA root.crt -CAkey root.key -CAcreateserial -out leaf.crt -sha256

# view cert
openssl x509 -in leaf.crt -text

other fun things