X.509 Certificate Structure: Fields & SAN Extension

How an issued X.509 certificate is actually built at the ASN.1 level — the fields a CSR doesn't have, the extensions mechanism that gives certificates their modern flexibility, and exactly how the SAN GeneralName types work underneath the domain list you're used to seeing.

🛠️ Related tool: Open Certificate Decoder →

What an X.509 Certificate Actually Is, Structurally

An issued certificate, defined in RFC 5280, is a single ASN.1 SEQUENCE built from three top-level parts: tbsCertificate (short for "to be signed"), signatureAlgorithm, and signatureValue. This is the same three-part shape a PKCS#10 CSR uses, and that similarity is deliberate — a certificate is, structurally, what a CA produces after taking the subject and public key from a CSR and wrapping them in a much richer container. tbsCertificate is where nearly everything lives: version, serial number, the issuer's identity, a validity window, the subject, the public key, and — in every modern certificate — an extensions field. None of the fields specific to certificates (issuer, validity, extensions with real binding effect) exist in a CSR at all; a CSR only ever contains what its subject requested, never what a CA actually decided to grant.

⭐
ToolsNovaHub Pro Tip
When comparing a CSR against the certificate eventually issued from it, expect the subject and public key to match but don't assume the extensions will — a CA can add, drop, or modify requested extensions freely, and SAN entries in particular sometimes get trimmed or reordered during issuance.
⚠️
Common Beginner Mistake
Assuming every field visible in a decoded certificate was something the certificate holder chose. Version, the extensions mechanism itself, and the criticality flag are all fixed parts of the X.509 schema — the CA and the schema control far more of the structure than the requester does.

Version and Serial Number: Two Small Fields With Real History

The version field is encoded as [0] EXPLICIT INTEGER — a context-specific tag wrapping the actual version integer, present because version has a DEFAULT value (v1) in the schema and only needs explicit encoding when it's anything else. Serial number looks like a trivial identifier but carries more weight than its size suggests: following a 2011 demonstration attack that exploited predictable, sequential serial numbers to engineer a certificate collision, the CA/Browser Forum's baseline requirements now mandate that every publicly trusted certificate's serial number contain at least 64 bits of output from a cryptographically secure random number generator. A serial number that looks suspiciously short or sequential in a decoded certificate is worth a second look — it can indicate an internal CA that hasn't adopted current entropy requirements.

Issuer and Subject: The Certificate-Specific Half of the Name Structure

Subject reuses exactly the same X.500-derived RDN structure a CSR's subject does — C, ST, L, O, OU, CN, encoded as SET OF SEQUENCE pairs of OID and value, the mechanics of which are covered in more depth in our companion guide on decoding a CSR's subject fields. What's new in a certificate is Issuer, a second Name of identical structure identifying whoever signed this certificate. When Issuer and Subject are field-for-field identical, the certificate signed itself — the expected shape for a root CA certificate sitting at the top of a trust chain, since nothing else exists above a root to sign it.

Validity: UTCTime, GeneralizedTime, and the 2050 Cutover

The Validity SEQUENCE holds exactly two Time values, notBefore and notAfter, and Time itself is an ASN.1 CHOICE between two concrete encodings. UTCTime packs a two-digit year into a fixed thirteen-character string (YYMMDDHHMMSSZ), interpreted per RFC 5280's rule that years 00–49 mean 2000–2049 and years 50–99 mean 1950–1999. GeneralizedTime instead uses a full four-digit year and is mandatory for any date from 2050 onward, since UTCTime's two-digit year simply can't represent it unambiguously. In practice this means every certificate issued today, with validity periods measured in months to a few years, still uses UTCTime — GeneralizedTime in validity fields mostly shows up in certificates deliberately dated decades out, such as some root CA certificates with multi-decade lifespans.

SubjectPublicKeyInfo: The One Field Identical to a CSR

The public key structure — an AlgorithmIdentifier naming RSA or ECDSA (and for ECDSA, the specific named curve) followed by the actual key material as a BIT STRING — is byte-for-byte the same SubjectPublicKeyInfo format a CSR uses. This isn't a coincidence of convenience; it's because the CA is meant to carry the exact public key from the CSR forward into the certificate unchanged. If you decode both a CSR and the certificate later issued from it, the SubjectPublicKeyInfo bytes should match precisely — a mismatch there would mean the certificate was issued against a different key entirely, which is a serious sign something went wrong in the issuance pipeline.

Extensions: The Mechanism a CSR Doesn't Have

Extensions live in a [3] EXPLICIT context tag wrapping a SEQUENCE OF Extension, where each Extension is itself { extnID OBJECT IDENTIFIER, critical BOOLEAN DEFAULT FALSE, extnValue OCTET STRING }. A CSR can only request extensions through its generic extensionRequest attribute, a mechanism bolted onto PKCS#10's much older 1990s design; a certificate's extensions field, by contrast, is a first-class part of the X.509v3 schema with real, binding effect on how the certificate may be used. This is the field that carries SAN, Basic Constraints, Key Usage, Extended Key Usage, Authority Key Identifier, and every other modern certificate behavior — none of which existed in the original 1988 X.509 specification at all.

The Criticality Flag: What Happens When a Client Doesn't Understand an Extension

Each Extension's optional critical BOOLEAN is a small field with an outsized practical consequence. Per RFC 5280, if a certificate-processing application encounters a critical extension it doesn't recognize or can't fully process, it's required to reject the certificate outright rather than silently skip the extension and proceed. Non-critical extensions, by contrast, may be safely ignored by software that doesn't understand them. This gives certificate issuers a genuine enforcement mechanism — marking Basic Constraints critical on a CA certificate, for instance, guarantees that any client too old or too limited to check whether a certificate is actually authorized to sign others will refuse to trust it, rather than quietly accepting a certificate it can't properly evaluate.

SAN's GeneralName Choices, in the Context of Real Certificates

Subject Alternative Name's value is a SEQUENCE OF GeneralName, and GeneralName is an ASN.1 CHOICE offering several distinct identifier types, each with its own context-specific tag: dNSName [2] for hostnames, iPAddress [7] for a raw IP address, rfc822Name [1] for an email address, and uniformResourceIdentifier [6] for a URI, among a few less common choices. Public web server certificates rely almost exclusively on dNSName, but public CAs do issue certificates using iPAddress directly for customers who need TLS on a bare IP address rather than a domain, and S/MIME email certificates lean on rfc822Name instead. Interestingly, SAN is marked non-critical in essentially every publicly issued certificate — slightly counterintuitive given how central it is to hostname validation today, but browsers are specifically hardcoded to always process SAN regardless of its criticality bit, so the flag's setting doesn't change SAN's practical importance one bit.

Basic Constraints and Key Usage as a Coordinated Pair

Basic Constraints' CA:TRUE/CA:FALSE value determines whether a certificate is allowed to sign other certificates at all, but it's typically paired with Key Usage's keyCertSign bit for the constraint to carry full weight — Basic Constraints says a certificate is permitted to act as a CA, while Key Usage's keyCertSign flag confirms the underlying key is specifically authorized to perform certificate-signing operations. A well-formed CA certificate carries both consistently (CA:TRUE alongside keyCertSign and typically cRLSign); a well-formed end-entity certificate carries neither, or explicitly sets CA:FALSE. Seeing one without the other during a decode is usually a signal the certificate was built by non-standard tooling rather than a mainstream CA.

Certificate Versions Compared: v1, v2, and v3

VersionYear IntroducedKey AdditionReal-World Use Today
v11988Base fields only — no extensions mechanismEssentially none; can't carry SAN, fails modern browser validation
v21993Optional issuer/subject unique identifiersRare; the unique identifier fields saw minimal real adoption
v31996General-purpose extensions fieldVirtually universal — every certificate a browser trusts today

The jump from v1 to v3 is really the story of X.509 gaining an extensibility mechanism it was never designed with initially — everything that makes a modern certificate flexible (SAN, constrained CA authority, key usage restrictions) exists only because v3 added a place to put it.

Reading a Real Certificate's Extensions Field by Field

Running openssl x509 -in file.crt -noout -text against any current certificate shows the extensions field rendered as a labeled list under X509v3 extensions:, each with its criticality noted in parentheses when set. A typical public web server certificate shows Subject Alternative Name (non-critical) with its domain list, Basic Constraints (usually critical) reading CA:FALSE, Key Usage (often critical) listing digitalSignature and keyEncipherment, Extended Key Usage (non-critical) listing TLS Web Server Authentication, and an Authority Key Identifier tying it back to whichever intermediate CA signed it. Comparing this against a root or intermediate CA certificate's extensions — CA:TRUE, keyCertSign and cRLSign in Key Usage, no Extended Key Usage at all — makes the structural difference between an end-entity and a CA certificate immediately visible.

Certificate vs CSR: What's Actually Different Structurally

FieldPresent in a CSR?Present in a Certificate?
Subject, Public KeyYesYes — carried forward unchanged
IssuerNoYes — required
Validity (notBefore/notAfter)NoYes — required
Extensions (binding)Requested only, via attributeYes — first-class field with real effect
CA SignatureSelf-signed only, proving key possessionYes — signed by the issuing CA's key

When You'd Actually Need to Understand This Structure

Most people who dig into certificate internals at this level land in one of a few situations. A developer debugging why a homegrown internal CA's certificates are being rejected traces the problem to a missing critical flag on Basic Constraints. A security engineer reviewing a vendor's PKI implementation checks whether serial numbers actually contain sufficient entropy, since a vendor cutting corners there is a real, if uncommon, finding. Someone building certificate-parsing tooling of their own needs to know exactly which fields are fixed by the schema versus genuinely optional before writing a parser that doesn't break on edge cases. And occasionally, someone comparing a CSR against the certificate eventually issued from it wants to understand precisely which fields should match and which are expected to differ.

Related Reading

For the structurally similar (but distinct) unsigned request format, see Decoding a CSR: Reading SAN & Subject Fields. To decode an actual issued certificate using this structure, use the Certificate Decoder. For how these certificates link together into a trust chain and the file formats they're stored in, see our companion guide Certificate Chains & PEM vs DER Encoding. For validation levels that determine what gets vetted before these fields are populated, read SSL Certificate Validation Levels: EV vs OV vs DV.

📅 Last updated: September 2026📜 Sourced from: RFC 5280

ToolsNovaHub guides are researched against primary sources (RFCs, vendor docs) and kept up to date as standards change. Spotted an error? Let us know.

📋 Related Tools & Guides Comparison

ResourceTypeLink
Certificate DecoderToolOpen Tool →
CSR DecoderToolOpen Tool →
Decoding a CSR: SAN & Subject FieldsGuideRead Guide →
Certificate Chains & PEM vs DER EncodingGuideRead Guide →
SSL Certificate CheckerToolOpen Tool →
Try it yourself — 100% free
🚀 Open Certificate Decoder

🔗 More Guides

FAQ

tbsCertificate ("to be signed" — version, serial number, issuer, validity, subject, public key, and extensions), signatureAlgorithm (which algorithm signed it), and signatureValue (the actual signature bytes over tbsCertificate). This mirrors a CSR's three-part shape but with more fields inside the first part.
Following a 2011 attack that exploited predictable serial numbers to forge a certificate collision, the CA/Browser Forum baseline requirements now mandate at least 64 bits of CSPRNG-derived entropy in every serial number CAs issue, specifically to make that class of attack infeasible.
A critical extension tells any client processing the certificate that it must understand and correctly handle that extension, or reject the certificate outright rather than silently ignore it. Non-critical extensions may be safely skipped by clients that don't recognize them.
Non-critical in virtually all publicly issued certificates, which is slightly counterintuitive given how central SAN is to hostname validation — but browsers are specifically written to always process SAN whether or not it's flagged critical, so the criticality bit doesn't change its practical importance.
Version 1 (1988) had no extensions mechanism at all. Version 2 (1993) added optional unique identifier fields that saw almost no real-world use. Version 3 (1996) added the general-purpose extensions field that everything modern — SAN, Basic Constraints, Key Usage — depends on, and is what essentially every certificate issued today uses.
Yes — the iPAddress GeneralName choice encodes a raw IP address rather than a hostname, and public CAs do issue certificates for IP addresses directly when a customer needs TLS on a bare IP rather than a domain name, though it's uncommon compared to dNSName usage.
They constrain different things and are usually needed together for the constraint to be meaningful — Basic Constraints alone says whether a certificate can sign other certificates, while Key Usage's keyCertSign bit confirms the key is actually permitted to perform that specific cryptographic operation. A CA certificate is expected to carry both consistently.
Yes, unlike the subject's internal RDN set — the top-level fields of tbsCertificate (version, serial, signature, issuer, validity, subject, publicKey, extensions) follow a fixed sequence defined by the ASN.1 schema itself, and a parser expects them in that exact order.
Per RFC 5280, it must reject the certificate rather than proceed — this is the entire point of the criticality flag, giving certificate issuers a way to guarantee a security-relevant constraint can't be silently bypassed by older or non-compliant client software.
A CSR can request extensions via its extensionRequest attribute, but it's only a request — the extensions field with real, binding effect exists solely inside the final signed certificate. A CA is free to grant, modify, or ignore what a CSR requested when it builds the actual extensions field.
Almost never intentionally on the public web — a v1 certificate can't carry SAN, so it would fail modern browser hostname validation entirely. Where v1 certificates do still appear is niche internal tooling or very old legacy systems that predate the SAN requirement.