Certificate signing requests
A certificate signing request is a signed statement saying "here is my public key, here is the identity I am claiming, and here is proof I hold the matching private key". The proof is a signature over the request made with that private key. You send the CSR to a certificate authority; the private key never leaves your machine. The CA then validates your claim to those names and issues a certificate — which may not match your request, because the CA decides what goes in it.
The three parties #
You CA Client
| | |
|-- generate key pair | |
|-- build CSR (public key | |
| + claimed identity, | |
| signed with private key) | |
|--------------------------->| |
| |-- validate domain |
| |-- issue certificate |
|<---------------------------| |
|-- deploy cert + key | |
|<------------------------------------------------------| TLS handshake
|-- prove key possession ------------------------------->| The private key appears exactly once in that diagram, on your side, and never moves.
What the self-signature proves #
A CSR is signed with the private key corresponding to the public key inside it. That signature does
not prove you own example.com; it proves the person submitting the request holds the key they are
asking to have certified.
Without it, an attacker could take your public key, submit it with their own identity, and obtain a certificate for a key they cannot use — pointless — or, more usefully, substitute their key into your request in transit. The self-signature closes that.
openssl req -in request.csr -noout -verify Expected output
Certificate request self-signature verify OK
What the CA does with it #
| In your CSR | What the CA does |
|---|---|
| Public key | Copies it into the certificate. This is the point of the exercise |
| Common Name | Usually copies it, but it has no effect on hostname matching |
| Subject alternative names | Keeps names you prove control of; drops the rest |
| Organisation, country | Verified for OV and EV; often stripped for DV |
| Key usage, extended key usage | Normally replaced by CA policy |
| Validity dates | Not in a CSR at all — the CA sets them |
The consequence: never assume the issued certificate mirrors the request.
openssl req -in request.csr -noout -text | grep -A1 "Subject Alternative Name"
openssl x509 -in certificate.crt -noout -ext subjectAltName Domain validation happens outside the CSR #
Anyone can generate a CSR for any hostname. Try it — nothing stops you:
openssl req -new -newkey rsa:2048 -nodes -keyout fake.key -out fake.csr \
-subj "/CN=www.google.com" -addext "subjectAltName=DNS:www.google.com" That file is a perfectly valid CSR. It is also worthless, because no CA will issue against it — validation is a separate step where you prove control of the domain by serving a token over HTTP, publishing a DNS record, or answering a documented email address.
The key pair is the thing that matters #
If you lose the private key, the CSR and any certificate issued from it become useless: you cannot complete a TLS handshake without the key. There is no recovery.
openssl req -in request.csr -noout -pubkey | openssl sha256
openssl pkey -in private.key -pubout | openssl sha256 Related #
Frequently asked questions
- Does the CA get my private key?
- No, and no legitimate CA will ever ask for it. The CSR contains only the public key plus a signature made with the private one. Any provider requesting a private key should be refused.
- What stops someone submitting a CSR for a domain they do not own?
- The CA's validation, not the CSR itself. Anyone can generate a CSR claiming any hostname. The CA proves domain control separately — an HTTP challenge, a DNS record, or an email to a documented address — before issuing.
- Can I reuse a CSR?
- Technically yes, if nothing has changed. It is a poor habit, because reusing the CSR normally means reusing the key, and rotating the key at renewal limits the damage from an exposure you have not noticed.
- Why does my issued certificate not match my CSR?
- Because the CSR is a request. The CA sets its own validity dates, drops hostnames you have not proven control of, and usually replaces extensions such as key usage with its own policy. Always inspect the certificate you receive.
References
- RFC 2986: PKCS #10 certification request syntax — the CSR structure itself
- RFC 6125: service identity in TLS — why the common name stopped being authoritative for hostnames