Introduction

Certificates and PKI (Public Key Infrastructure) are difficult, and many people choose to bypass this topic. This is because in the security field, many things cannot be done perfectly, and the involved domains are both broad and deep. For example, it involves mathematics, encryption, algorithms, and more. But what’s most confusing are the various certificate formats and encryption algorithms - just remembering the names is already a headache for most people!

But in the end, I still forced myself to learn these things. For this purpose, I even read a book called “Serious Cryptography: Practical Modern Encryption,” which took a long time, but the harvest wasn’t significant!

Later, I studied Smallstep’s open-source projects and tried to deploy a private ACME Server. Through this exploration, I discovered that the purpose of certificates and PKI is actually very simple: to associate “names” with public keys!

Why Learn PKI

I believe PKI enables a person to think about how to define a system at the encryption level (and even at a broader security level). Specifically, PKI technology:

  • Is universal and vendor-neutral;
  • Can be applied anywhere, allowing systems distributed worldwide to communicate securely with each other;
  • Is conceptually simple and very flexible; if we use our TLS everywhere model, we don’t even need VPNs.

TL;DR

The purpose of certificates and PKI: to associate names with public keys. This is the highest abstraction of certificates and PKI; everything else belongs to implementation details.

Concepts

X.509

X.509 is a standard format for public key certificates in cryptography.

ASN.1

ASN.1 (Abstract Syntax Notation One) is a standard that describes a flexible notation for data representation, encoding, transmission, and decoding.

Encoding Formats

Common encoding formats include the following two types:

  • DER: a binary encoding format;
  • PEM: a text encoding format, usually with extensions like .pem, .crt, .cer.

Entity

An Entity is anything that exists - even if it only exists logically or conceptually. For example:

  • You yourself are an Entity;
  • The computer you use is an Entity;
  • The code you write is also an Entity;
  • The multigrain pancake you had for breakfast is also an Entity;
  • The ghost you saw when you were six is also an Entity — even if your mother told you there are no ghosts in the world, it’s just your imagination.

Identity

Every entity has an identity. It’s difficult to define this concept precisely, but let’s put it this way: identity is what makes you you, understand?

In the computer field, identity is usually represented by a series of attributes describing a specific entity. These attributes include group, age, location, favorite color, shoe size, and so on.

Identifier

An Identifier is not the same thing as Identity: each Identifier is a unique identifier that is uniquely associated with an Entity that has an Identity.

For example: I am George, but George is not my Identity, it’s just a Name - although the two are synonymous in our small-scale discussion.

Claim

An Entity can Claim that it possesses a certain Name or Names.

Claims are not only associated with Names but can be associated with other things as well. For example: I can Claim anything: age, gender, permissions, etc.

Authentication

Other Entities can authenticate this Claim to confirm the truth of the statement. Generally speaking, the purpose of authentication is to confirm the legitimacy of certain Claims.

Subscriber

An Entity that can be the Subject of a certificate is called a Subscriber (certificate Owner) or End Entity.

Correspondingly, Subscriber certificates are sometimes also called End Entity Certificates or Leaf Certificates, the reason for which will be discussed later when we talk about Certificate Chains.

CA

CA (Certificate Authority) is an Entity that issues certificates to Subscribers and is a type of Certificate Issuer.

CA certificates are usually called Root Certificates or Intermediate Certificates, depending on the type of CA.

Relying Party

A Relying Party is a Certificate User who verifies whether certificates issued by a CA (to Subscribers) are legitimate.

An Entity can be both a Subscriber and a Relying Party. That is, a single Entity can both have its own certificate and use other certificates to authenticate Remote Peers, such as in mutual TLS (mTLS) scenarios.

These terms are sufficient for our upcoming discussion. We will now get to the main topic and see how certificate claims and authentication are implemented in practice. For more terminology, please refer to RFC 4949.

Certificates: Driver’s Licenses for Computers and Code

As mentioned earlier, public key encryption systems allow us to know who we’re communicating with, but this is based on the premise that we know (have) the other party’s public key.

So what if the other party doesn’t know my public key? This is where certificates come into play.

Think about it, our requirements are actually very simple:

  • First, we need to send the public key and its owner information to the other party;
  • But this information alone is not enough; we also need to make the other party believe this information.

Certificates are used to solve this problem, and the solution is to ask an authority trusted by both parties to certify (sign) the above information.

Certificate Content: Public Key and Name

  • A certificate is a data structure that contains a Public Key and a Name;
  • The authority signs the certificate, and the signature roughly means: Public Key XXX is associated with Name XXX;

The Entity that signs a certificate is called the Issuer (or Certificate Authority, CA), and the Entity in the certificate is called the Subject.

For example, if an Issuer issues a certificate for Bob, the content can be interpreted as follows:

A certificate is an ID issued by an authority, and there’s nothing magical about it

Here, Some Issuer is the certificate issuer (certificate authority), and the certificate is to prove that this is Bob’s public key. Some Issuer is also the signatory of this claim.

The Essence of Certificates: Learning Other Public Keys Based on Trust in the Issuer’s Public Key

From the above, we know that if we know Some Issuer’s public key, we can authenticate (Authenticate) the certificates it issues (with its private key) by verifying the signature. If you trust Some Issuer, then you can trust this claim.

Therefore, certificates enable everyone to learn the public keys of other Entities (in the example above, Bob) based on trust in and knowledge of the Issuer’s public key. This is the essence of certificates.

Analogy with Driver’s Licenses

Certificates are like driver’s licenses or passports for computers/code. If you’ve never seen me before but trust the DMV, you can use my driver’s license for authentication:

  • First, verify that the license is genuine (check hologram, etc.);
  • Then confirm that my face matches the photo;
  • Then see that the name is mine, and so on.

Authorities issue certificates

Computers do similar things with certificates: if they’ve never communicated with another computer before but trust certain certificate authorities, they can use certificates for authentication:

  • First, verify that the certificate is legitimate (check the signature using the certificate issuer’s public key, etc.);
  • Then extract the public key and name from the certificate;
  • Then use the subscriber’s public key to verify the subscriber’s signature over the network;
  • Check if the name is correct, and so on.

Still comparing with driver’s licenses:

  • Driver’s license: describes whether you are qualified to drive;
  • Certificate: describes whether you are a CA, whether your public key can be used for signing or encryption;
  • Both have validity periods.

There are many details in the figure above, and many things will be discussed below. But ultimately, it all comes down to the summary at the beginning of this article: certificates are simply things that bind names to public keys. Everything else is implementation details.

PKI

By now, we know the origin and appearance of certificates, but this is only half of this article. Let’s look at how certificates are created and used.

Public key infrastructure (PKI) is a general term that includes everything we need when interacting with certificates and key management: issuance, distribution, storage, use, verification, revocation, etc. Like “database infrastructure,” this term is intentionally vague.

  • Certificates are the building blocks of most PKIs, and certificate authorities are their foundation.
  • PKI includes libraries, cron jobs, protocols, conventions, clients, servers, people, processes, names, discovery mechanisms, and all the other stuff you’ll need to use public key cryptography effectively.

Building a PKI from scratch is an extremely large task, but in reality, some simple PKIs don’t even use certificates. For example,

  • When editing the ~/.ssh/authorized_keys file, you’re configuring a simple certificate-less PKI. SSH implements the binding of Public Key and Name within a flat file in this way;
  • PGP uses certificates but not CAs, instead using a web-of-trust model;
  • You can even use blockchain to Assign Names and Bind them to Public keys.

If you’re building a PKI from scratch, the only certain thing is that you’ll need public keys; everything else varies with the design.

The following will mainly focus on PKI used in the Web domain, as well as internal PKI that follows existing standards based on Web PKI technology.

The goal of certificates and PKI is actually very simple: to bind names to public keys. Keep this in mind in the following content.

Web PKI vs Internal PKI

Web PKI is used when browsers access HTTPS links. Although there are some issues, it has greatly improved web security and is basically transparent to users. It should be enabled in all possible cases when accessing internet web services.

  • Web PKI is defined by RFC 5280, and the CA/Browser Forum (a.k.a., CA/B or CAB Forum) has further refined it.
  • It is sometimes also called “Internet PKI” or PKIX (After the working group that created it).

PKIX and CAB Forum documents cover a lot of content. They define various certificates discussed earlier, as well as what a “name” is and where it’s located in the certificate, what signature algorithms can be used, how RPs determine the Issuer’s certificate, how to specify the Validity Period (Issue and expiry dates) of a certificate, revocation, Certificate Path Validation, how CAs determine if someone owns a domain name, and so on.

Web PKI is important because browsers use Web PKI certificates by default.

Internal PKI is the PKI that users use for their own product infrastructure, including:

  • Services, containers, virtual machines, etc.;
  • Enterprise IT applications;
  • Company endpoint devices such as laptops, phones, etc.;
  • Other code or devices that need identification.

Internal PKI allows you to authenticate and establish encrypted channels so that your services can communicate securely with each other anywhere on the public internet.

With Web PKI, Why Use Your Own Internal PKI?

First, simply put: Web PKI’s design did not consider internal use cases. Even with CAs like Let’s Encrypt that provide free certificates and automated delivery, users still need to handle things like rate limits and availability themselves. This is very inconvenient if you have many services and frequent deployments.

Additionally, in Web PKI, users have little or no control over many important details such as certificate lifecycle, revocation mechanisms, renewal processes, key types, algorithms, etc. As we’ll see below, these are all very important things.

Finally, the CA/Browser Forum Baseline Requirements actually prohibit associating Web PKI CAs with Internal IPs (e.g., 10.0.0.0/8) and Internal DNS names that aren’t fully-qualified and resolvable in public global DNS (e.g., You can’t bind a kubernetes cluster DNS name like foo.ns.svc.cluster.local). If you need to bind to these Names in certificates, or issue a large number of certificates, or control certificate details, you need your own Internal PKI.

As we’ll see in the next section, trust (or lack thereof) is another reason to avoid using Web PKI for internal scenarios.

In summary, it is recommended to:

  • Use Web PKI for public-facing services or APIs;
  • Use Internal PKI for all other scenarios.

Trust & Trustworthiness

Trust Stores

As introduced earlier, certificates can be interpreted as a Statement or Claim, for example:

The Issuer says: The public key of this Subject is XXX.

The Issuer will sign this statement, and the Relying Party can verify (Authenticate) whether the signature is legitimate (through the Issuer’s public key). But we actually skipped an important question here: how does the Relying Party know the Issuer’s public key?

Pre-configured Trusted Root Certificates

The answer is actually very simple: Relying Parties pre-configure a list of trusted root certificates (also called Trust anchors) in their Trust store.

The manner in which this pre-configuration occurs is a very important aspect of PKI:

  • One way is to Bootstrap from another PKI: you can use some automation tools to copy the root certificate to the Relying Party via SSH. This uses the SSH PKI mentioned earlier.
  • If you’re on the Cloud, then the PKI dependency hierarchy (trust chain) goes one step deeper: SSH PKI is bootstrapped by Web PKI plus authentication, where authentication is the method you chose when creating your Cloud account.

Chain of Trust

If you trace back along this chain of trust far enough, you’ll eventually find people: every chain of trust ends in the real world (Meatspace).

Chain of Trust

The following diagram illustrates this more clearly:

Trust Chain

Root Certificate Self-Signing

Root certificates in the trust store are self-signed: the Issuer and Subject are the same.

Logically, this kind of Statement represents: Mike says: Mike’s public key is XXX.

A self-signed certificate ensures that the Subject/Issuer knows the corresponding private key, but anyone can generate a self-signed certificate with any name they want to write in it.

Therefore, the provenance of the certificate is crucial: a self-signed certificate should only be trusted when the process by which it enters the trust store is trustworthy.

  • On macOS, the trust store is managed by Keychain;
  • On some Linux distributions, it might just be some files under /etc or other paths;
  • If your users can modify these files, it’s best to confirm that you trust these users first.

Sources of Trust Stores

So where do trust stores come from? For Web PKI, the most important relying parties are browsers. The trust stores used by mainstream browsers by default — and anything else that uses TLS — are maintained by four organizations:

  • Apple’s root certificate: for iOS/macOS programs
  • Microsoft’s root certificate program: used by Windows
  • Mozilla’s root certificate program: used by Mozilla products, and due to its openness and transparency, also serves as the foundation for some other trust stores (e.g., for many Linux distributions)
  • Google doesn’t maintain a root certificate program (Chrome typically uses the trust store of the operating system it’s running on), but maintains its own blacklist of root certificates or specific certificates it doesn’t trust. (ChromeOS builds off of Mozilla’s certificate program)

Operating System Trust Stores

The trust stores in operating systems usually come with the system.

  • Firefox comes with its own trust store (distributed via TLS from mozilla.org — bootstrapping off of Web PKI using some other trust store).
  • Programming languages and other non-browser things like curl typically use the operating system’s trust store by default.

Therefore, this trust store is typically used by default by many pre-installed things on the system; it’s updated through software updates (which typically use another PKI for signing).

Trust stores typically contain over 100 common certificate authorities maintained by these programs. Some famous ones include:

  • Let’s Encrypt
  • Symantec
  • DigiCert
  • Entrust

If you want programmatic control:

  • Cloudflare’s cfssl project maintains a github repository that includes the trusted certificates from various trust stores to assist with certificate bundling (which we’ll discuss momentarily).
  • For a more human-friendly experience you can query Censys to see which certificates are trusted by Mozilla, Apple, and Microsoft.

Trustworthiness

These 100+ certificate authorities are theoretically trusted — browsers and some other software trust certificates issued by these authorities by default.

However, this doesn’t mean they are trustworthy. There have been incidents where Web PKI certificate authorities provided fake certificates to government agencies to snoop on traffic or impersonate certain websites. Some of these “trusted” CAs operate in places outside of jurisdiction — including both democratic and authoritarian countries.

  • The NSA has taken every opportunity to undermine Web PKI. In 2011, two “trusted” certificate authorities, DigiNotar and Comodo, were both compromised. The DigiNotar certificate leak may have been related to the NSA.
  • Additionally, there are many CAs that issue incorrectly formatted or incompatible certificates. Therefore, although these CAs are trusted according to industry standards, they are unreliable (untrustworthy) based on experience.

We’ll soon see that the security of Web PKI depends on the security of the least secure authority (the least secure CA). This is obviously not what we want.

The browser community has been taking action to address these issues. The CA/Browser Forum Baseline Requirements specify rules that these trusted certificate authorities should follow when issuing certificates. As part of the WebTrust audit project, CA compliance is audited before adding a CA to certain trust stores (such as Mozilla’s).

If internal scenarios are already using TLS, you probably don’t need to trust these public CAs in most cases. If you do trust them, you open a door to hell for the NSA and other organizations: your system’s security will depend on the weakest of over 100 organizations.

Internal PKI Uses Separate Trust Stores

In any case, if you use your own internal PKI, you should maintain a separate trust store for internal services. That is,

  • Don’t add your root certificate directly to the system’s existing trust store,
  • Instead, configure internal TLS to only use your own root certificates.

Internal PKI Fine-Grained Control: CAA & SPIFFE

If you want better federation internally — for example, limiting which certificates an internal CA can issue,

  • You can try CAA records and properly configure RPs.
  • You can also look at SPIFFE, which is an evolving project aimed at standardizing some internal PKI-related issues.

What is a Certificate Authority

We’ve already discussed many CA-related things, but we haven’t defined what a CA is.

  • A Certificate Authority (CA) is a trusted certificate issuer.
  • A CA guarantees the binding relationship between a public key and a name by signing a certificate.
  • Essentially, a CA is just another certificate plus the corresponding private key used to sign other certificates.

Obviously, some logic and processes are needed to connect these things. A CA needs to distribute its certificate to trust stores, accept and process certificate requests, and issue certificates to subscribers.

  • A CA that exposes such APIs for external calls and automates these processes is called an online CA.
  • Those self-signed root certificates in trust stores are called root certificate authorities (root CAs).

Web PKI Cannot Automate Certificate Issuance

CAB Forum Baseline Requirements 4.3.1 explicitly states that a Web PKI CA’s root private key can only sign certificates through a direct command.

  • In other words, Web PKI root CAs cannot automate the certificate signing process.
  • This is a problem for any large CA operation. It’s impossible to manually type a command every time a certificate needs to be issued.

This requirement is for security reasons.

  • Web PKI root certificates are widely present in trust stores and are difficult to revoke. Intercepting a root CA private key could theoretically affect billions of people and devices.
  • Therefore, best practice is to ensure that root private keys are offline, ideally on some dedicated hardware connected to physically isolated devices with good physical security and strict usage procedures.

Some internal PKIs also follow similar practices, but this isn’t actually necessary.

  • If you can automate root certificate rotation (for example, by updating trust stores through configuration management or orchestration tools), you can easily rotate a compromised root key.
  • Due to people’s obsession with root key management for internal PKI, the deployment efficiency of internal PKI is greatly reduced. Your AWS root account credentials are at least confidential information too, so how do you manage them?

Intermediates, Chains, and Bundling

With the premise that the Root CA is offline, to make certificate issuance scalable (for example, to make automation possible), the Root private key is only used in rare cases,

  • to sign a few intermediate certificates.
  • Then Intermediate CAs (also called Subordinate CAs) use the corresponding Intermediate private keys to issue Leaf certificates to subscribers.

As shown in the following diagram:

Certificate Issuance Path

Intermediates are usually not included in trust stores, so they are easier to revoke or rotate, thus enabling Certificate issuance to be online and automated.

This certificate bundling mechanism consisting of Leaf, Intermediate, and Root forms a certificate chain.

  • Leaf is issued by Intermediate,
  • Intermediate is issued by Root,
  • Root signs itself.

Technically speaking, the examples above are simplified; you can create longer chains and more complex graphs (for example, Cross-certification). But this is not recommended because complexity can quickly get out of control. In any case, End entity certificates are leaf nodes, which is why they are called Leaf certificates.

When configuring a Subscriber (for example: Apache, Nginx, Linkderd, Envoy), you typically need not only the leaf certificate but also a Certificate bundle containing Intermediates.

  • Sometimes PKCS#7 and PKCS#12 are used because they can contain a complete certificate chain.
  • More often, the certificate chain is encoded as a simple sequence of line-separated PEM objects.

Here’s an example:

cat server.crt
  -----BEGIN CERTIFICATE-----
  MIICFDCCAbmgAwIBAgIRANE187UXf5fn5TgXSq65CMQwCgYIKoZIzj0EAwIwHzEd
  ...
  MBsGA1UEAxMUVGVzdCBJbnRlcm1lZGlhdGUgQ0EwHhcNMTgxMjA1MTc0OTQ0WhcN
  HO3iTsozZsCuqA34HMaqXveiEie4AiEAhUjjb7vCGuPpTmn8HenA5hJplr+Ql8s1
  d+SmYsT0jDU=
  -----END CERTIFICATE-----
  -----BEGIN CERTIFICATE-----
  MIIBuzCCAWKgAwIBAgIRAKBv/7Xs6GPAK4Y8z4udSbswCgYIKoZIzj0EAwIwFzEV
  ...
  BRvPAJZb+soYP0tnObqWdplmO+krWmHqCWtK8hcCIHS/es7GBEj3bmGMus+8n4Q1
  x8YmK7ASLmSCffCTct9Y
  -----END CERTIFICATE-----

RP: Certificate Path Validation

Since Intermediate Certificates are not included in trust stores, they need to be distributed and verified just like Leaf certificates.

  • As mentioned earlier, when configuring a Subscriber, these Intermediates need to be provided, and Subscribers subsequently pass them to RPs.
  • If using TLS, this process happens during the TLS handshake.
  • When a Subscriber sends its certificate to a Relying party, it includes all Intermediates that can prove it comes from a trusted root certificate.
  • The Relying party verifies the Leaf and Intermediate certificates through a process called Certificate path validation.

Certificate Path Validation

The complete Certificate path validation algorithm is quite complex. It includes:

  • Checking certificate expirations
  • Revocation status
  • Various certificate policies
  • Key use restrictions
  • A bunch of other stuff

Obviously, it’s crucial for PKI RPs to accurately implement this algorithm.

  • If you disable Certificate path validation (for example, curl -k), you’ll face significant risks, so don’t disable it.
  • Completing proper TLS isn’t that difficult; Certificate path validation is the part of TLS that completes authentication.

Some might say that since the Channel is already encrypted, disabling it doesn’t matter. Wrong! It does matter. Encryption without authentication is worthless!

It’s like confessing in church: what you say is private, but you don’t know who’s behind the curtain — except this isn’t church, it’s the internet.

Key and Certificate Lifecycle

Before being able to use certificates through protocols like TLS, you need to configure how to obtain a certificate from a CA. Logically, this is a fairly simple process:

  • The Subscriber who needs a certificate first generates a Key pair themselves, then sends it to the CA through a request,
  • The CA checks if the associated Name is correct, and if so, signs and returns a certificate.

Certificates expire, and expired certificates won’t be trusted by RPs. If a certificate is about to expire and you still want to use it, you need to renew and rotate it. If you want RPs to stop trusting a certificate before it expires, you need to perform revocation.

Like most things related to PKI, these seemingly simple processes are actually full of pitfalls. They also hide two of the hardest problems in computer science: cache consistency and naming. But on the other hand, once you understand the underlying principles, looking back at some things that are actually in use becomes much simpler.

DN (Distinguished Names)

Historically, X.509 used X.500 Distinguished Names (DN) to name the subject of a certificate, i.e., the Subscriber. A DN includes a Common Name (for me, the author, it would be “Mike Malone”), and can also include Locality, Country, Organization, Organizational Unit, and some other things.

  • Nobody understands DNs, and they don’t have much meaning on the internet.
  • You should avoid using DNs. If you really need to use them, keep them as simple as possible.
  • There’s no need to use all fields, and in fact, you shouldn’t use all fields.
  • The Common Name might be the only field you need to use; if you’re a thrill seeker, you can also use an Organization Name.

PKIX stipulates that a website’s DNS Hostname should be associated with the DN Common name. Recently, the CAB Forum has deprecated this requirement, making the entire DN field optional (Baseline Requirements, sections 7.1.4.2).

SAN (Subject Alternative Name)

Modern best practice uses the Subject Alternative Name (SAN) X.509 Extension to Bind Names in certificates.

There are four commonly used types of SANs, all binding widely used names:

  • Domain names (DNS)
  • Email addresses
  • IP addresses
  • URIs

In the context we’re discussing, these are all unique, and they map well to the things we want to identify:

  • Email addresses for people
  • Domain names and IP addresses for machines and code,
  • URIs if you want to get fancy

You should use SANs, as shown in the highlighted lines 11 and 30 below:

step certificate inspect https://george.betterde.com
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 277028619957168996496866148377847610215553 (0x32e1d2b7678a3cde0a0aff3d8973da00c81)
    Signature Algorithm: SHA256-RSA
        Issuer: C=US,O=Let's Encrypt,CN=R3
        Validity
            Not Before: Nov 15 07:22:21 2022 UTC
            Not After : Feb 13 07:22:20 2023 UTC
        Subject: CN=george.betterde.com
        Subject Public Key Info:
            Public Key Algorithm: RSA
                Public-Key: (4096 bit)
                ........
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                Server Authentication, Client Authentication
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Subject Key Identifier:
                91:AC:86:05:F8:94:F1:26:6F:4A:CE:DA:04:F2:69:52:00:55:81:D2
            X509v3 Authority Key Identifier:
                keyid:14:2E:B3:17:B7:58:56:CB:AE:50:09:40:E6:1F:AF:9D:8B:14:C2:C6
            Authority Information Access:
                OCSP - URI:http://r3.o.lencr.org
                CA Issuers - URI:http://r3.i.lencr.org/
            X509v3 Subject Alternative Name:
                DNS:george.betterde.com

Note that Web PKI allows binding multiple Names within a single certificate, and Names are also allowed to use wildcards. This means,

  • For domain name wildcard certificates, a certificate can have multiple SANs, and can also have SANs like *.smallstep.com.
  • This is useful for websites with multiple domain names.

Generating Key Pairs

With a Name, you need to generate a key pair before creating a certificate. As mentioned earlier: the security of PKI fundamentally depends on the simple fact that only the Entity corresponding to the Subscriber Name in the certificate should possess the private key corresponding to that certificate. To ensure this condition is met,

  • Best practice is for the Subscriber to generate its own key pair, so only it knows the private key.

  • You should absolutely avoid sending private keys over the network.

  • There is now a slow but clear trend from RSA towards elliptic curve keys (ECDSA or EdDSA).

  • If you decide to use RSA keys, make sure they are at least 2048 bits long, but not more than 4096 bits.

  • If you use ECDSA, then the P-256 curve is probably the best choice (secp256k1 or prime256v1 in openssl), unless you’re concerned about the NSA, in which case you can choose something fancier, such as EdDSA with Curve25519 (but support for these keys is not yet very good).

Here’s an example of using openssl to generate an elliptic curve P-256 key pair:

openssl ecparam -name prime256v1 -genkey -out k.prv
openssl ec -in k.prv -pubout -out k.pub

# You can also use step to generate
step crypto keypair --kty EC --curve P-256 k.pub k.prv

You can also generate these certificates programmatically, which allows certificates to never touch the disk.

Issuance (Ensuring the Information in the Certificate is Correct)

After a Subscriber has a Name and a Key pair, the next step is to obtain a Leaf certificate from a CA. For a CA, it needs to prove two things:

  • The public key in the Subscriber’s certificate is indeed the Subscriber’s public key (for example, verifying that the Subscriber knows the corresponding private key); this step is usually implemented through a simple technical mechanism: Certificate Signing Request (CSR).

  • The Name to be bound in the certificate is indeed the Subscriber’s Name. This step is much harder. Abstractly, this process is called Identity Proofing or Registration.

Certificate signing requests (PKCS#10)

When a Subscriber requests a certificate, they submit a certificate signing request (CSR) to the CA.

  • A CSR is also an ASN.1 structure, defined in PKCS#10.

  • Similar to certificates, the CSR data structure includes a public key, a name, and a signature.

  • CSRs are self-signed, signed with the private key corresponding to the public key in the CSR.

    • This signature is used to prove that the subscriber has the corresponding private key and can decrypt anything encrypted with its public key.
    • It also ensures that even if the CSR is copied or forwarded, its contents cannot be tampered with (tampering would be invalid).
  • CSRs include many certificate detail configuration items. But in practice, most configuration items are ignored by the CA. Most CAs use their own fixed templates or provide an administrative interface to collect this information. An example of creating a key pair and CSR using the step command:

step certificate create -csr test.smallstep.com test.csr test.key

Conclusion

Public key encryption systems allow computers to see each other on the network.

  • If I have a public key, I can “see” that you have the corresponding private key, but I cannot use this private key myself.
  • If I don’t yet have the other party’s public key, I need certificates to help. Certificates associate public keys with the names of private key owners; they are like driver’s licenses for computers and code.
  • Certificate authorities (CAs) sign certificates with their private keys, guaranteeing these binding relationships; they are like the DMV.
  • If you present a driver’s license issued by the DMV, and your face matches the photo on the license, others can believe you are the person (name) on the license. Similarly, if you are the only Entity that knows a certain key, and the certificate you give me comes from a CA I trust, then I believe that the name in the certificate is you.

In reality, most certificates are X.509 v3 certificates, defined in ASN.1 format, usually serialized as PEM-encoded DER. The corresponding private keys are usually represented as PKCS#8 Objects, also serialized as PEM-encoded DER. If you use Java or Microsoft products, you might encounter PKCS#7 and PKCS#12 encapsulation formats.

The encryption field has heavy historical baggage, making these current things very frustrating to learn and use. This is more frustrating than not wanting to learn a technology because it’s too difficult.

PKI is a general term for everything involved when using public key infrastructure: Names, Key types, Certificates, CAs, Cron jobs, Libraries, etc.

  • Web PKI is the PKI used by browsers by default. Web PKI CAs are trusted but not trustworthy.
  • Internal PKI is the PKI that users build and maintain themselves. It’s needed because Web PKI is not designed for internal use cases; Internal PKI is easier to automate and scale, and allows users to control many details, such as Naming and certificate lifetime.
  • It’s recommended to use Web PKI on the public internet and your own internal PKI for internal networks (for example, use TLS instead of VPN).
  • Smallstep Certificate Manager makes building an internal PKI very simple.

To obtain a certificate, you need to name and generate a certificate. It’s recommended to use SANs for names:

  • DNS SANs for code and machines
  • EMAIL SANs for people
  • If none of these can be used, use URI SAN

Key type is a big topic, but almost unimportant: you can change key types at will, and in fact, encryption itself (crypto) is not the weakest link in PKI.

To obtain a certificate from a CA, you need to submit a CSR and prove the applicant’s identity. Use certificates with shorter lifecycles and Passive Revocation. Automate the certificate renewal process. Don’t disable Certificate path validation.

Finally, as stated at the beginning: certificates and PKI associate names with public keys; everything else is details.

I hope this is helpful, Happy hacking…