Skip to main content
RunBook Academy

OPNsenseXXIV · PKI and CertificatesPKI and certificate management

Certificate signing requests — what a CSR really contains

Intermediate⏱ ~14 min🧪 Lab requiredopensslssh

What you'll learn

  • Explain what a CSR contains and why a CA cannot read private keys
  • Generate a CSR with OpenSSL or OPNsense for a specific service hostname
  • Decode and inspect a CSR before submitting it to a CA
  • Match a CSR to the matching private key to detect mismatches
  • Identify the CSR mistakes that lead to invalid or rejected certificates

Prerequisites

Verified against OPNsense 25.x · FreeBSD 14.x · PF (FreeBSD packet filter) FreeBSD 14.x · Unbound 1.20+ · Kea DHCP OPNsense 25.x plugin · WireGuard in-kernel + OPNsense plugin · strongSwan (IPsec plugin) OPNsense 25.x plugin · OpenVPN 2.6.x · Suricata 7.x · 2026-08-14

Not yet marked complete on this device.

A certificate signing request is a small, signed file that asks a certificate authority to issue a certificate. The CSR contains the public key, the identity the certificate should bind, and a self-signature proving the requester holds the private key corresponding to the public key. The CA reads the CSR, signs the public key and identity with its own private key, and returns a certificate.

This lesson covers what a CSR contains at the field level, how to generate one for an OPNsense service, how to decode a CSR before submitting it to a CA, and the production mistakes that lead to invalid certificates — wrong SAN, mismatched private key, deprecated signature algorithm, and the rest.

What a CSR is

The CSR is defined by PKCS#10 (RFC 2986). The data structure:

CertificationRequest:
  certificationRequestInfo:
    version:            0 (PKCS#10 v1)
    subject:            the identity being certified (CN, O, C, ...)
    subjectPKInfo:      the public key and algorithm
    attributes:         extensions (SAN, key usage, ...)
  signatureAlgorithm:   the algorithm signing the CSR
  signature:            signature over certificationRequestInfo

The CSR is signed with the private key corresponding to the public key in the CSR. This is the proof that the requester holds the private key — the CA never sees the private key, only the public key embedded in the CSR. The CA verifies the signature, confirms the requester is allowed a certificate, attaches its own signature, and returns a certificate.

The CSR is usually encoded as PEM (base64 with BEGIN/END markers), sometimes as DER (raw ASN.1 binary). The OPNsense CA manager and most public CAs accept PEM.

-----BEGIN CERTIFICATE REQUEST-----
MIICjDCCAXQCAQAwGTEXMBUGA1UEAwwOZi5leGFtcGxlLmNvbTCCASAwDQYJ
KoZIhvcNAQEBBQADggENADCCAQgCggEBAKvV0pD+exampleCSRbody...
-----END CERTIFICATE REQUEST-----

Generating a CSR

OPNsense generates the CSR for you under System → Trust → Certificates. The workflow:

  1. Add a certificate.
  2. Choose Create a Certificate Signing Request.
  3. Select the key type, size, and the CA that should eventually sign it (this only matters if OPNsense will sign it; if the CSR is going to an external CA, leave it blank or pick any CA, the field is not part of the CSR).
  4. Set the Common Name, Organisation, Country, and other DN fields.
  5. Add the Subject Alternative Names. This is the part that matters for hostname validation.
  6. Click Save.

OPNsense generates the private key, builds the CSR, and stores both. The CSR is exported from the certificate list as a .csr file.

For a CLI-only generation (the same flow, by hand):

Configuration changeopenssl req new
$ openssl req -new -newkey rsa:3072 -nodes -keyout fw.example.com.key -out fw.example.com.csr -subj "/CN=fw.example.com/O=Example Org/C=GB" -addext "subjectAltName=DNS:fw.example.com,DNS:fw.internal.example.com" -addext "keyUsage=digitalSignature,keyEncipherment" -addext "extendedKeyUsage=serverAuth"
Generating a RSA private key
...........................................................................++++
writing new private key to 'fw.example.com.key'
-----

Illustrative output

The -nodes flag stores the private key unencrypted. This is required for services that start without operator input (the firewall GUI, IPsec daemons). For an offline signing key (such as the CA root), -nodes should not be used — passphrase- protect the offline key.

Decoding and inspecting a CSR

Before sending a CSR to a CA, decode it. The verification catches mistakes that would otherwise produce an unusable certificate.

Read-only / Safeopenssl req decode
$ openssl req -in fw.example.com.csr -noout -text -reqopt ext_subjected,ext_extensions
Certificate Request:
  Data:
      Version: 1 (0x0)
      Subject: CN = fw.example.com, O = Example Org, C = GB
      Subject Public Key Info:
          Public Key Algorithm: rsaEncryption
              RSA Public-Key: (3072 bit)
              Modulus:
                  00:c1:9a:...
              Exponent: 65537 (0x10001)
      Attributes:
      Requested Extensions:
          X509v3 Subject Alternative Name:
              DNS:fw.example.com, DNS:fw.internal.example.com
          X509v3 Key Usage:
              Digital Signature, Key Encipherment
          X509v3 Extended Key Usage:
              TLS Web Server Authentication
  Signature Algorithm: sha256WithRSAEncryption
       a3:51:c9:...

Illustrative output

The fields to inspect, in order:

  1. Subject DN: the Common Name must match the primary hostname. The Organisation, Country, etc. should be correct.
  2. Subject Alternative Name: must list every hostname the service will be reached at. This is what the verifier checks at TLS time.
  3. Public Key Algorithm: must be modern (RSA 2048+, ECDSA P-256+, Ed25519). Avoid RSA 1024 or smaller.
  4. Signature Algorithm: must be SHA-256 or stronger. Avoid SHA-1 (deprecated, rejected by modern CAs).
  5. Requested Extensions: Key Usage and Extended Key Usage should match the purpose (serverAuth for TLS servers, clientAuth for TLS clients).

Matching CSR to private key

A CSR is a public object, sent to a CA. The private key stays with the requester. After the CA returns the certificate, the requester must verify that the certificate’s public key matches the private key they kept. A mismatched key pair produces a certificate the requester cannot use.

Read-only / Safekey match check
$ diff <(openssl req -in fw.example.com.csr -noout -pubkey) <(openssl x509 -in fw.example.com.crt -noout -pubkey)

Illustrative output

Common CSR mistakes in production

Five mistakes appear repeatedly.

  1. Missing SAN. The CSR has a CN but no SAN. The CA issues a certificate with no SAN. Modern clients refuse to validate the hostname. The service is broken until the CSR is regenerated.
  2. Wrong hostname. The CN and SAN list fw.example.com but the service is reached as firewall.example.com. The TLS handshake fails for clients using the real hostname.
  3. Deprecated signature algorithm. SHA-1 with RSA. The CA refuses to sign. Modern CAs reject SHA-1 CSRs outright.
  4. Mismatched private key. The CSR was regenerated, but the operator kept the old private key. The CA issues the certificate from the new CSR, the new public key does not match the old private key, the service is broken.
  5. Passphrase-protected private key for an auto-start service. The service starts unattended and cannot type the passphrase. The service fails to start, or starts in a broken state.

Summary

  • A CSR carries the public key, the subject identity, the SAN, and a self-signature proving the requester holds the private key. The CA never sees the private key.
  • Generate CSRs with OPNsense or OpenSSL. Include the SAN; modern clients do not match the CN.
  • Decode the CSR with openssl req -text before submitting it to the CA. Verify subject, SAN, key algorithm, signature algorithm, and extensions.
  • After the CA returns the certificate, verify the public key matches the private key on disk.
  • Never regenerate a CSR without informing the CA. A lost CSR plus a submitted CSR produces an unusable certificate.

Knowledge check · 4 questions

  1. Q1. Why does the CSR protocol work without the CA ever seeing the private key?

  2. Q2. A CSR with Common Name "fw.example.com" but no Subject Alternative Name extension is acceptable for a TLS server certificate because the Common Name will be matched by modern clients.

  3. Q3. After receiving a certificate from a CA, which of the following checks must the operator perform? Select all that apply.

  4. Q4. You generate a CSR, submit it to the CA, and then realise the SAN was missing a hostname. You regenerate the CSR with the correct SAN and submit it. What happens to the certificate issued from the first CSR?

Passing score: 75%. Answers are checked in this browser.