PKI, TLS, and mTLS: The OpenSSL Values That Actually Matters
Beyond the basic tutorials: a practical guide to the flags, fields, and trust traps that actually break production.
Most TLS/PKI tutorials show you the commands. Fewer show you which values in those commands are the ones that actually decide whether your certificate does what you think it does. After enough time working with certificate authorities, keystores, and mutual TLS between services, a handful of fields and flags turned out to matter far more than the rest.
Before any of that, though — the four terms in this post’s title, explained the way I wish someone had explained them to me first.
The Basics, Actually Explained (The Passport Analogy)
To understand certificates, it helps to stop thinking about computers and start thinking about international travel.
- The Certificate (Your Passport): A digital ID card that proves your public key belongs to your identity. Crucially, you cannot just declare your own identity (writing “I am the bank” on a napkin doesn’t work). Someone else has to vouch for you and stamp it.
- The Certificate Authority or “CA” (The Passport Office): The trusted entity that verifies who you are and stamps your certificate.
- The Root CA (The Government): The absolute top of the trust chain. Everyone agrees to trust them directly. To handle the workload, the Root CA vouches for “Intermediate CAs” (regional passport offices), allowing them to issue certificates on the Root’s behalf.
- PKI or Public Key Infrastructure (The Global System): The entire ecosystem that makes these ID cards actually mean something. It’s the passport office, the international treaties that make Country A accept Country B’s passports, and the “no-fly lists” for when a passport needs to be revoked.
The Connection: TLS vs. mTLS
Now that we have identities, how do computers actually talk to each other?
TLS (Transport Layer Security) This is what creates the little padlock in your web browser. It does two things at once:
- Encrypts: It scrambles the conversation so no one eavesdropping can read it (a sealed envelope).
- Authenticates: It proves the server is who it claims to be (a wax seal you verify before opening the envelope). Without authentication, you might be having a perfectly encrypted conversation with a scammer.
mTLS (Mutual TLS) Standard TLS is a one-way street: the server proves its identity to you, but the server has no idea who you are beyond your IP address. It’s like a bouncer proving they work at the club, but letting you walk in without checking your ID.
mTLS is a two-way street. Both sides show their badges. The client verifies the server, and the server verifies the client’s certificate before responding. This is essential for internal service-to-service traffic. It guarantees not just, “Am I talking to the payments service?” but also, “Am I legally authorized to ask the payments service for money?”
With that vocabulary in place, here’s where the actual values that matter live.
The CSR: Where Identity Actually Gets Decided
A Certificate Signing Request is a config file plus a keypair — it’s the “application form” you submit to a CA, saying “please vouch for this public key under this identity.” The keypair almost never causes problems. The config file is where identity gets decided.
[ req ]
default_bits = 2048
distinguished_name = req_distinguished_name
prompt = no
[ req_distinguished_name ]
countryName = LK
organizationName = Example Corp
organizationalUnitName = platform-core
commonName = auth.internal.example.comHere are the specific fields that cause the most headaches if misunderstood:
commonName(CN): Historically, this was the main identity field (e.g.,api.example.com). Modern systems are supposed to ignore it in favor of the SAN (Subject Alternative Name), but plenty of internal tools still read it. The trap: It is never safe to let your CN and SAN contradict each other.organizationalUnitName(OU): It is incredibly easy to treat this as just a cosmetic label (like "Platform Team"). Don't. Downstream systems often validate the entire distinguished name, not just the CN. If you change the OU to fix a typo, you haven't corrected a certificate—you've created a completely new identity that might be rejected silently.prompt = no: A tiny setting that saves pipelines. Without it, OpenSSL stops and waits for a human to interactively type in every field. If you forget this in an automated CI/CD pipeline, your build will hang indefinitely.
The Golden Rule for Renewals When replacing an existing certificate, decode the current one and copy its exact field values. Do not guess. Do not try to reconstruct it from what you assume the naming convention should be. Reconstructing fields from memory is the fastest way to cause a self-inflicted outage.
openssl x509 -in current-cert.pem -noout -subject -ext subjectAltNameIf there’s a typo in a live, trusted certificate, that typo is now part of its identity. “Fixing” it in the CSR doesn’t correct the cert — it issues a different cert that happens to look similar, and anything pinned against the old identity breaks silently.
SAN vs. CN, and Why “Every Cert Needs a SAN” Isn’t Always True
subjectAltName (SAN) is what modern TLS actually validates hostnames against:
[ req_ext ]
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = auth.internal.example.com
DNS.2 = authMultiple SANs are how one cert covers a service’s DNS name, its short internal name, and any legacy alias, without issuing three separate certs.
Get Yohan Senadheera’s stories in your inbox
Join Medium for free to get updates from this writer.
But not every certificate needs one. Some internal, non-hostname-validated use cases (an internal signing cert, for instance) are legitimately CN-only, with no req_extensions block at all. The mistake isn't leaving SAN out where it belongs — it's assuming every CSR template needs one and adding it where the real, previously-issued certificate never had it. Same rule as before: check the actual cert, don't assume the template.
Keystores: What openssl pkcs12 Is Actually Doing
A signed cert plus its private key, packaged together, is a PKCS12 keystore (.p12/.pfx) — the format most Java and Kubernetes-adjacent tooling expects instead of raw PEM files.
Building one:
openssl pkcs12 -export \
-in signed-cert.pem \
-inkey private-key.pem \
-out keystore.pfx \
-password pass:"$KEYSTORE_PASSWORD" \
-name "service-alias"Unpacking one — this direction is just as common, usually when pulling a cert back out of storage to inspect it or feed it into a truststore:
# Extract just the certificate
openssl pkcs12 -in keystore.pfx -nokeys -passin pass: | openssl x509 -out cert.pem# Extract just the private key
openssl pkcs12 -in keystore.pfx -nocerts -nodes -passin pass: | openssl rsa -out key.pemThe
-nameFlag Trap: This flag sets the keystore's alias. If downstream tooling looks up the key by a specific alias name, an export without-name(or with the wrong one) produces a keystore that loads perfectly fine but fails at lookup time—usually with a cryptic error that doesn't mention aliases at all.
Chain Validation vs. Thumbprint Pinning: The Distinction That Actually Bites
This is the one concept that causes real production incidents if it’s not understood, because both approaches “work” until a certificate gets rotated.
Chain validation — trust anything signed by a CA you already trust:
Trusted: Root CA
Presented: any cert signed by Root CA
Result: validThumbprint (fingerprint) pinning — trust one exact certificate, by its SHA-1/SHA-256 hash:
Trusted: [ "specific-fingerprint-abc123..." ]
Presented: a different cert, also validly signed by the same trusted CA
Result: rejectedChain validation is what most people picture when they think “TLS trust” — it’s PKI working as designed, trusting the passport office rather than memorizing every passport. Thumbprint pinning is stricter and shows up more often than expected in mTLS setups that predate a proper CA — when there was no trusted issuer to chain-validate against, pinning the one known-good cert’s fingerprint was the only option available.
The trap: a certificate rotation is a completely valid, properly-signed event from the CA’s point of view, and thumbprint pinning breaks anyway, because the fingerprint changed even though nothing about trust actually did. If you’re migrating a system from self-signed certs to a real CA, this is the thing to check for before you rotate anything: is the consuming side validating the chain, or pinning a specific fingerprint? They fail completely differently when the cert underneath them changes.
openssl x509 -in cert.pem -noout -fingerprint -sha1If that value shows up hardcoded in a trust list somewhere, rotating the cert it belongs to needs that list updated in the same change — not as a follow-up once something breaks.
Summary
- A certificate is a signed identity claim, PKI is the system that makes signing meaningful, TLS is the encrypted-and-authenticated connection, and mTLS is that same handshake with both sides showing ID.
- Never reconstruct CSR fields from assumption when replacing an existing cert. Decode the real one; a “corrected” typo issues a different identity.
- SAN is what modern clients validate against, but not every legitimate cert needs one — check before adding.
openssl pkcs12 -export/-nokeys/-nocertscovers most of what a keystore pipeline does; don't forget-nameif anything looks up the key by alias.- Chain validation and thumbprint pinning are not interchangeable trust models, and the difference only shows up the moment someone rotates a certificate. Know which one you’re relying on before you touch anything upstream of it.









