Skip to content
ecdsa.com

Public key from a certificate · OpenSSL

How to extract the public key from an X.509 certificate with OpenSSL

To extract the public key from an X.509 certificate with OpenSSL, run openssl x509 -in cert.pem -noout -pubkey: it prints the SubjectPublicKeyInfo as a PEM "BEGIN PUBLIC KEY" block. This recipe also computes the key's SHA-256 fingerprint and base64 pin, and checks that a private key belongs to the certificate by comparing public halves.

Tested with OpenSSL 3.6.4 (Debian forky (buildpack-deps:forky-curl)).

the public key as SPKI PEM, its SHA-256 fingerprint and base64 pin
# The certificate's public key as SubjectPublicKeyInfo PEM ("BEGIN PUBLIC KEY")
openssl x509 -in cert.pem -noout -pubkey > pub.pem
cat pub.pem
# SHA-256 of the SPKI: the key's fingerprint, and (base64) the pin HPKP-style pinning uses
openssl pkey -pubin -in pub.pem -outform DER | openssl dgst -sha256 -c
openssl pkey -pubin -in pub.pem -outform DER | openssl dgst -sha256 -binary | base64
check that key.pem is the certificate's private key
# Does key.pem belong to this certificate? Compare the public halves.
if [ "$(openssl x509 -in cert.pem -noout -pubkey)" = "$(openssl pkey -in key.pem -pubout)" ]; then
echo "key.pem matches cert.pem"
fi

How it works

  1. openssl x509 -noout -pubkey prints the certificate's SubjectPublicKeyInfo — algorithm identifier plus key — as -----BEGIN PUBLIC KEY-----, the format every library imports.
  2. openssl pkey -pubin -outform DER turns it into DER; SHA-256 over those bytes is the key fingerprint (45:ca:a7:e3:…:7b:5f here), and its base64 (Rcqn43J0…e18=) is the pin used by SPKI pinning (Android network security config, OkHttp, the former HPKP).
  3. A private key belongs to a certificate when its public half is the same SPKI: compare openssl pkey -in key.pem -pubout with the certificate's -pubkey output, as the second snippet does.
  4. The certificate in the run is a P-256 leaf; the same commands work for RSA, Ed25519 and other keys.

Gotchas

  • openssl x509 -fingerprint hashes the whole certificate (CD:B1:A1:40…), not the key — it changes at every renewal, while the SPKI hash stays the same as long as the key does.
  • Without -noout, openssl x509 -pubkey prints the public key and then the certificate (2 PEM blocks in the run); scripts that save the output get both.

Related recipes