Is this how X509 certificates are verified to be valid?

  1. The receiver receives the certificate
  2. Look at the issuer of the cert, and find the public key of that CA (its hardcoded in the application or the OS)
  3. Decrypt the signature using the public key
  4. Compute the hash over the cert (not including the signature?)
  5. If the hash matches the decrypted signature, and the receiver trusts the CA and its public key, the certificate is valid and the public key in the cert is safe to use

About step 4, over what fields is the hash computed? Is it the whole cert but not including the signature?

  • Note verifying the signatures on a cert chain, although important, is not nearly enough by itself to validate (i.e. trust) the 'end-entity' aka 'leaf' cert. See rfc 5280 section 6, or the linked dupe #127095 (disclosure: though not the first author, I wrote some parts of the answer) Commented Feb 17, 2023 at 0:59

1 Answer 1


What fields? All of them. An X.509 Public Key Certificate is, sort of, only 3 fields: "the stuff to sign" (TbsCertificate "To-Be-Signed Certificate"), "how I signed it", "the signature". The TbsCertificate is what contains everything that are sensibly thought of as a certificate's fields.


Certificate  ::=  SEQUENCE  {
    tbsCertificate       TBSCertificate,
    signatureAlgorithm   AlgorithmIdentifier,
    signatureValue       BIT STRING  }

TBSCertificate  ::=  SEQUENCE  {
    version         [0]  EXPLICIT Version DEFAULT v1,
    serialNumber         CertificateSerialNumber,
    signature            AlgorithmIdentifier,
    issuer               Name,
    validity             Validity,
    subject              Name,
    subjectPublicKeyInfo SubjectPublicKeyInfo,
    issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
                         -- If present, version MUST be v2 or v3
    subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
                         -- If present, version MUST be v2 or v3
    extensions      [3]  EXPLICIT Extensions OPTIONAL
                         -- If present, version MUST be v3

As for your steps:

  1. Yes, and (for a correctly behaving server) also all of the certificates up to, but not including, the root certificate for that chain.
  2. The root certificate will ultimately be part of the OS (or data added to the OS after the fact), but a normal TLS server on the internet has a 3 certificate chain: the end-entity/leaf certificate, an intermediate issuer, and the root. The intermediate's public key verifies the signature in the leaf certificate, the root verifies the one in the intermediate, and the system trusts the root.
  3. No. "Decrypt the signature" is never how signatures are computed. For RSA signatures there's a step that looks an awful lot like decryption, but it's a different operation. For DSA, ECDSA, EdDSA, or any other signature algorithm "decrypt" makes no sense.
  4. Computing hashes is really a detail of the signature algorithm. For RSA/DSA/ECDSA it's true that the signature computation involves hashing the data first, and many libraries will accept just the hash. For EdDSA (pure, not the "ph" variant), hashes are involved, but it's not just over the input data... so this step is sort of overly specific.
  5. This is sort of how classic RSA signature verification works, but, as mentioned, RSA isn't the only algorithm.

Steps 3-5 are really one logical step of "perform signature verification per the algorithm used to sign the certificate". What that entails is different for RSA, RSA-PSS, DSA (defunct), ECDSA, EdDSA, EdDSAph, GOST R 34.10-2012, and any other signature algorithm.

Not the answer you're looking for? Browse other questions tagged .