How X.509 Certificates Work: ASN.1, DER Encoding, and PKI Validation

X.509 is the standard format for public key certificates used throughout the internet. Every time your browser establishes an HTTPS connection, it receives and validates an X.509 certificate. Every Certificate Authority, every trust store, every Certificate Transparency log, and every revocation check via OCSP or CRL operates on X.509 certificates. The format is defined in RFC 5280, rooted in the ITU-T X.509 standard first published in 1988 as part of the X.500 directory services framework. Understanding how X.509 certificates are structured, encoded, and validated is fundamental to understanding the security of the modern internet.

ASN.1 and DER: How Certificates Are Encoded

X.509 certificates are not free-form text. They are binary data structures defined using Abstract Syntax Notation One (ASN.1), a schema language for structured data that predates JSON and Protocol Buffers by decades. ASN.1 defines the types and structure of the certificate fields. The actual binary encoding uses Distinguished Encoding Rules (DER), a strict subset of the Basic Encoding Rules (BER) that guarantees a single unique encoding for any given data structure. This uniqueness is critical because certificates are cryptographically signed — if two different encodings of the same logical data were possible, signature verification could break.

DER uses a Tag-Length-Value (TLV) encoding scheme. Every element starts with a tag byte identifying the data type (INTEGER, BIT STRING, SEQUENCE, etc.), followed by the length of the value in bytes, followed by the value itself. A SEQUENCE tag wraps an ordered collection of elements, like a struct. A SET groups unordered elements. An OBJECT IDENTIFIER (OID) is a globally unique identifier expressed as a sequence of integers — for example, 1.2.840.113549.1.1.11 identifies the SHA-256 with RSA signature algorithm. OIDs are allocated hierarchically by standards bodies: 1.2.840.113549 is the arc for RSA Security, 2.5.4 is the arc for X.500 attribute types.

While DER is the canonical binary format, certificates are often transported in PEM (Privacy-Enhanced Mail) format, which is simply DER data encoded in Base64 and wrapped between -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- delimiters. PEM is a text-safe encoding for transmission over protocols that do not handle raw binary well. You can convert between them using openssl x509 -inform PEM -outform DER. Tools like openssl asn1parse will decode the raw ASN.1 structure of any certificate, revealing the exact TLV nesting.

A common point of confusion: PKCS#1 defines the RSA-specific key format, PKCS#8 wraps any private key with algorithm identification, and PKCS#12 (.p12/.pfx) bundles a certificate with its private key in a password-protected archive. These are all distinct from X.509, which defines only the certificate format. The private key is never part of the certificate.

Certificate Structure: The Three Top-Level Components

Every X.509v3 certificate is a SEQUENCE of exactly three elements:

X.509 Certificate (SEQUENCE) 1. TBSCertificate (To-Be-Signed) version: v3 (0x2) serialNumber: unique integer per CA signature: algorithm OID (e.g. sha256WithRSA) issuer: DN of the signing CA validity: notBefore / notAfter timestamps subject: DN of the certificate holder subjectPublicKeyInfo: algorithm + public key bits extensions: [v3] SAN, key usage, basic constraints... This is the data that gets hashed and signed 2. Signature Algorithm OID: 1.2.840.113549.1.1.11 (sha256WithRSA) 3. Signature Value BIT STRING: the CA's digital signature CA signs hash of TBSCertificate to produce Signature Value Algorithm must match in both TBS and outer SEQUENCE

The TBSCertificate (To-Be-Signed Certificate) contains all the meaningful data: identity, public key, validity period, and extensions. It is the exact byte sequence that the Certificate Authority hashes and signs. The Signature Algorithm identifies the hash-and-sign algorithm used (this field must match the algorithm OID inside TBSCertificate). The Signature Value is the raw cryptographic signature produced by the CA's private key over the DER-encoded TBSCertificate. To verify a certificate, you re-hash the TBSCertificate bytes and check the signature against the issuing CA's public key.

Certificate Fields in Detail

Version

X.509 has gone through three versions. Version 1 (1988) defined the basic fields. Version 2 (1993) added issuer and subject unique identifiers, which are almost never used in practice. Version 3 (1996) added extensions, which transformed X.509 from a rigid format into a flexible one. Virtually every certificate on the internet today is version 3. The version field is encoded as an integer: 0 means v1, 1 means v2, 2 means v3. It is context-tagged as [0] EXPLICIT in the ASN.1 definition and defaults to v1 if absent.

Serial Number

The serial number is a positive integer assigned by the CA that must be unique within that CA's scope. Combined with the issuer DN, it uniquely identifies a certificate worldwide. The CA/Browser Forum Baseline Requirements mandate that serial numbers contain at least 64 bits of output from a cryptographically secure random number generator. This randomization prevents certain collision attacks against hash functions — the chosen-prefix collision attack against SHA-1 demonstrated in 2019 is harder to exploit when the CA controls the serial number and injects entropy. Serial numbers can be up to 20 octets (160 bits) long per RFC 5280.

Signature Algorithm

This OID specifies the algorithm the CA used to sign the certificate. Common values include:

Certificates signed with SHA-1 (sha1WithRSAEncryption) have been distrusted by all major browsers since 2017 due to practical collision attacks. Post-quantum algorithms like ML-DSA (Dilithium) are being standardized for future X.509 use.

Issuer and Subject

Both the issuer and subject fields are Distinguished Names (DNs), inherited from the X.500 directory tradition. A DN is a SEQUENCE of Relative Distinguished Names (RDNs), each containing one or more attribute-value pairs. Common attributes:

For a self-signed root CA, the issuer and subject fields are identical. For an end-entity certificate, the issuer matches the subject of the CA that signed it. This is the fundamental linkage that builds the chain of trust.

Validity Period

The validity field contains two timestamps: notBefore and notAfter. Certificates are valid only within this window. The CA/Browser Forum has progressively shortened maximum certificate lifetimes for publicly-trusted TLS certificates: from 5 years, to 3 years, to 2 years, to the current maximum of 398 days (effective September 2020). Apple announced in 2024 a plan to reduce this to 47 days by 2028. Shorter lifetimes reduce the window of exposure if a private key is compromised and encourage automation of certificate renewal via protocols like ACME (used by Let's Encrypt).

Timestamps are encoded as either UTCTime (for dates through 2049) or GeneralizedTime (for dates from 2050 onward). Root CA certificates typically have validity periods of 20-30 years because changing root certificates requires updating trust stores in every operating system and device.

Subject Public Key Info

This field contains two elements: an algorithm identifier specifying the key type, and a BIT STRING containing the actual public key. For RSA keys, the public key is a SEQUENCE of the modulus (n) and public exponent (e), typically 65537. For ECDSA keys, it is an uncompressed or compressed elliptic curve point. For Ed25519 keys, it is 32 raw bytes.

The public key in this field is what TLS clients use during the handshake — the server proves it possesses the corresponding private key by signing the handshake transcript. This binding between identity (subject/SAN) and public key is the entire purpose of a certificate.

X.509v3 Extensions

Extensions transformed X.509 from a simple identity binding into a rich policy framework. Each extension has three components: an OID identifying the extension type, a critical flag (boolean), and the extension value (an OCTET STRING containing DER-encoded data specific to that extension type). If an extension is marked critical, any implementation that does not recognize it must reject the certificate. Non-critical extensions can be ignored if unrecognized.

Subject Alternative Name (SAN)

The Subject Alternative Name extension (OID 2.5.29.17) is arguably the most important extension in modern certificates. It lists the identities the certificate is valid for. A SAN can contain:

Since 2012, the CA/Browser Forum has required that all TLS certificates include at least one dNSName in the SAN extension. Relying parties (browsers, HTTP clients) must match against the SAN, not the CN. Most major TLS libraries, including Go's crypto/x509 since Go 1.15 and Chrome since 2017, will reject certificates that only have a CN without a matching SAN. Let's Encrypt never populates the CN field at all in some configurations, putting everything in the SAN.

Key Usage

The Key Usage extension (OID 2.5.29.15) is a bit field restricting how the public key in the certificate may be used. It is typically marked critical. The defined bits are:

A typical end-entity TLS certificate has digitalSignature set. An RSA end-entity certificate for TLS 1.2 may also have keyEncipherment. A CA certificate has keyCertSign and cRLSign. A key with keyCertSign but without the Basic Constraints CA flag is treated as invalid by compliant implementations.

Extended Key Usage (EKU)

The Extended Key Usage extension (OID 2.5.29.37) narrows the certificate's purpose beyond what Key Usage specifies. Common EKU OIDs:

The CA/Browser Forum requires that TLS server certificates include id-kp-serverAuth in their EKU. Intermediate CAs that issue TLS certificates must also have this EKU (or no EKU, which is interpreted as "any purpose"). The EKU constraint system prevents a certificate issued for code signing from being repurposed as a TLS certificate, even if the Key Usage bits would technically allow it.

Basic Constraints

The Basic Constraints extension (OID 2.5.29.19) is one of the most critical fields in the entire X.509 system. It contains a boolean cA flag indicating whether this certificate is a CA (and thus authorized to issue other certificates), and an optional pathLenConstraint integer limiting the number of intermediate CAs below this one. This extension must be marked critical in CA certificates.

Without Basic Constraints, any end-entity certificate could potentially be used to sign additional certificates, creating an unauthorized sub-CA. The TurkTrust incident in 2013 demonstrated the danger: TurkTrust accidentally issued intermediate CA certificates to two organizations that should have received regular end-entity certificates. One of those certificates was used to sign a fraudulent *.google.com certificate. Proper Basic Constraints enforcement would have prevented this — but some implementations at the time did not strictly check it.

A pathLenConstraint of 0 means the CA can issue end-entity certificates but cannot create further intermediate CAs. A value of 1 allows one level of intermediate CA below it. Root CAs typically omit the path length constraint, allowing arbitrary depth. In practice, most modern PKI hierarchies are two or three levels deep: root CA, one or two intermediates, and end-entity certificates.

Authority Information Access (AIA)

The AIA extension (OID 1.3.6.1.5.5.7.1.1) tells relying parties where to find additional information about the issuing CA. It typically contains two access methods:

CRL Distribution Points

The CRL Distribution Points extension (OID 2.5.29.31) lists URLs where the CA publishes its Certificate Revocation List. CRLs are signed lists of serial numbers that the CA has revoked before their expiration date. This extension provides an alternative or complement to OCSP-based revocation checking.

Authority Key Identifier and Subject Key Identifier

The Authority Key Identifier (AKI) extension (OID 2.5.29.35) identifies which CA key signed this certificate, using a hash of the CA's public key. The Subject Key Identifier (SKI) extension (OID 2.5.29.14) provides a hash of the certificate's own public key. Together, AKI and SKI form a chain: an end-entity certificate's AKI matches its issuing intermediate's SKI, and the intermediate's AKI matches the root's SKI. This linkage allows implementations to efficiently build certificate chains even when distinguished names are ambiguous or when a CA has re-keyed.

Certificate Policies

The Certificate Policies extension (OID 2.5.29.32) lists OIDs identifying the policies under which the certificate was issued. These OIDs correspond to the CA's Certification Practice Statement (CPS). For TLS certificates, the CA/Browser Forum defines three validation levels:

Certificate Chains and the Chain of Trust

A single X.509 certificate is not enough to establish trust. Trust requires a chain — an ordered sequence of certificates starting with the end-entity certificate (the one the server presents) and ending at a root CA certificate that the client already trusts. Each certificate in the chain is signed by the next certificate's public key.

OS / Browser Trust Store ~150 pre-installed root CAs Root CA Certificate (self-signed) Issuer = Subject = "ISRG Root X1" found in Intermediate CA Certificate Subject: "R11" Issuer: "ISRG Root X1" signed by End-Entity Certificate Subject: "god.ad" Issuer: "R11" signed by Validation: 1. Server sends EE + Intermediate 2. Client verifies EE sig with Intermediate's public key 3. Client verifies Intermediate sig with Root's public key 4. Root is self-signed and found in trust store → chain valid Sent in TLS Certificate message

In a typical TLS handshake, the server sends its own certificate followed by any intermediate certificates needed to build the chain. The root certificate is not sent — the client must already have it in its trust store. If a server fails to send intermediate certificates, clients that do not have them cached will fail to validate the chain. This is one of the most common TLS configuration errors, and tools like openssl s_client -showcerts or curl -v will reveal it immediately.

Root CAs and Trust Stores

A root CA certificate is self-signed: its issuer and subject are the same, and it is signed by its own private key. A self-signed certificate has no external validation — it is trusted solely because it has been explicitly included in a trust store by the operating system or browser vendor.

Major trust stores include:

Getting a root CA into these trust stores requires rigorous audits (WebTrust or ETSI), compliance with the CA/Browser Forum Baseline Requirements, and years of track record. Removal from a trust store — as happened to DigiNotar (2011), CNNIC (2015), WoSign/StartCom (2016), and Symantec (2018) — effectively kills a CA's ability to issue publicly-trusted certificates.

Root CA private keys are kept in Hardware Security Modules (HSMs) stored in physically secured facilities. Root keys are typically used only to sign intermediate CA certificates, and the root is kept offline. An intermediate CA's private key compromise is recoverable (revoke the intermediate, issue a new one); a root key compromise is catastrophic because there is no higher authority to revoke it — the only remedy is to remove it from every trust store worldwide.

Path Validation: RFC 5280 Algorithm

RFC 5280 Section 6 defines the certification path validation algorithm, which is the authoritative specification for how a relying party verifies a certificate chain. The algorithm is more complex than "check each signature" — it enforces policy constraints, name constraints, and validity at every level. Here is the simplified sequence for a chain of depth n:

  1. Initialization — Select a trust anchor (root CA). Set the working issuer name to the trust anchor's subject DN, the working public key to the trust anchor's public key, and the maximum path depth to the configured limit.
  2. For each certificate i = 1 to n:
    • Verify the signature on certificate i using the working public key.
    • Check that the certificate's issuer DN matches the working issuer name.
    • Check that the current date/time is within the certificate's validity period (notBefore ≤ now ≤ notAfter).
    • Check that the certificate has not been revoked (via CRL or OCSP).
    • Check the issuer name against Name Constraints, if any were set by a higher CA.
    • Process policy extensions: Certificate Policies, Policy Mappings, Policy Constraints, and Inhibit anyPolicy.
  3. For each CA certificate (i = 1 to n-1):
    • Verify Basic Constraints: the cA flag must be TRUE.
    • Verify Key Usage: the keyCertSign bit must be set.
    • Check path length: if pathLenConstraint is present, the number of remaining CA certificates below must not exceed it.
    • Process Name Constraints: any permittedSubtrees or excludedSubtrees restrict what subject names and SANs are allowed in certificates below this point.
    • Update the working issuer name and working public key for the next iteration.
  4. For the end-entity certificate (i = n):
    • Check that the subject or SAN matches the intended hostname.
    • Check Extended Key Usage for the intended purpose (e.g., id-kp-serverAuth for TLS).
    • Process any critical extensions — reject if any are unrecognized.
  5. Wrap-up — If all checks pass, the path is valid. If any check fails, the entire chain is rejected.

In practice, implementations like OpenSSL, BoringSSL, and Go's crypto/x509 add additional checks beyond RFC 5280. For example, Go enforces the SAN requirement (rejecting CN-only certificates), enforces minimum RSA key sizes (2048 bits), and rejects certificates with SHA-1 signatures. Chrome enforces Certificate Transparency requirements (SCTs), which is not part of RFC 5280 but is required by browser policy.

Name Constraints: Scoping CA Authority

The Name Constraints extension (OID 2.5.29.30) allows a CA to restrict the namespaces that subordinate CAs can certify. It contains two optional lists:

Name constraints are powerful for enterprise PKI. A company can obtain an intermediate CA certificate from a public root CA with a name constraint limiting it to their own domain (e.g., .corp.example.com). This allows the company to issue certificates internally without the root CA having to sign each one, while preventing the intermediate from issuing certificates for arbitrary domains. However, name constraints are complex to implement correctly and have historically been buggy in many TLS libraries.

CA/Browser Forum Baseline Requirements

The CA/Browser Forum is an industry consortium of CAs and browser vendors that publishes the Baseline Requirements — a binding set of rules that all publicly-trusted CAs must follow. Key requirements include:

Violations of the Baseline Requirements can result in a CA being distrusted by browser vendors. The process is typically gradual — a browser may first require the CA to explain the incident via a public Bugzilla report (Mozilla's process), then impose restrictions, and ultimately remove the CA's roots if problems persist. The Symantec distrust in 2018 followed years of documented non-compliance.

Cross-Signing and Bridge CAs

A new CA faces a bootstrapping problem: its root certificate is not in any trust store, so its certificates are not trusted by existing clients. Cross-signing solves this by having an established CA sign the new CA's root or intermediate certificate. The resulting cross-signed certificate has the same subject and public key as the new CA's self-signed root, but is signed by the established CA, making it chainable to an already-trusted root.

Let's Encrypt is the best-known example. When Let's Encrypt launched in 2015, its root (ISRG Root X1) was not yet in any trust store. IdenTrust cross-signed the ISRG Root X1, allowing Let's Encrypt certificates to chain through IdenTrust's DST Root CA X3, which was already universally trusted. As trust stores gradually added ISRG Root X1 directly, the cross-sign became less necessary. The IdenTrust cross-sign expired on September 30, 2021, causing issues for devices with outdated trust stores (notably Android 7.0 and earlier, and older OpenSSL versions that did not handle alternate chain building correctly).

Cross-signing creates multiple valid chain paths for the same end-entity certificate. Path building implementations must be able to discover and select the optimal path. Some implementations (like Go's crypto/x509) build all possible paths and select the shortest one that terminates at a trusted root.

Certificate Lifecycle

The full lifecycle of an X.509 certificate involves several stages:

  1. Key generation — the applicant generates a key pair locally. The private key never leaves the applicant's control.
  2. CSR creation — the applicant creates a Certificate Signing Request (CSR, defined by PKCS#10 / RFC 2986), which contains the public key, the requested subject DN, and requested extensions (particularly the SAN). The CSR is signed with the applicant's private key to prove possession.
  3. Validation — the CA verifies the applicant's identity and domain control according to the Baseline Requirements.
  4. Issuance — the CA constructs the TBSCertificate, signs it, and returns the complete certificate. The certificate is simultaneously submitted to CT logs.
  5. Deployment — the applicant installs the certificate and private key on the server, along with any intermediate certificates.
  6. Renewal — before the certificate expires, the process repeats. ACME (RFC 8555) automates this entirely.
  7. Revocation — if the private key is compromised or the certificate is no longer needed, the CA marks it as revoked. Revocation status is communicated via OCSP responses or CRL entries.

Common Failures and Debugging

X.509 validation failures are among the most frequently encountered errors in TLS deployments. Understanding the common causes saves hours of debugging:

The canonical debugging tool is openssl s_client:

openssl s_client -connect god.ad:443 -showcerts 2>&1 | \
  openssl x509 -noout -text

This connects to a server, retrieves the certificate chain, and decodes the end-entity certificate into human-readable form, showing every field and extension. For deeper ASN.1 inspection, openssl asn1parse -i shows the raw TLV structure with indentation.

X.509 vs. Other Certificate Systems

X.509 is not the only certificate system in use. Understanding the alternatives clarifies where X.509 fits:

See It in Action

X.509 certificates secure the connection between your browser and this page. The infrastructure that issues, distributes, and validates these certificates is itself visible at the network layer. Use the god.ad BGP Looking Glass to explore the networks that power the certificate ecosystem:

Every certificate chain traces back to a root CA whose infrastructure lives on specific networks, reachable via specific BGP routes. Look up any CA's IP address to see the AS path your OCSP queries and CRL downloads traverse. The trust model of X.509 ultimately depends on the security of the routing layer beneath it — which is why technologies like RPKI and BGP hijack detection are critical to the integrity of the certificate ecosystem.

See BGP routing data in real time

Open Looking Glass
More Articles
How TLS/HTTPS Works: Securing the Internet's Traffic
Certificate Transparency: How CT Logs Secure the Web's PKI
How Firewalls Work: Packet Filtering, Stateful Inspection, and Beyond
What is Cross-Site Scripting (XSS)?
What is Cross-Site Request Forgery (CSRF)?
What is Server-Side Request Forgery (SSRF)?