Certificate signing request
A CSR is a public request: bind these names to this public key. The private key never leaves the machine that made it. The CA answers with a certificate.
The CSR is the ask: take this public key and bind it to this subject and these SAN names. The private key never travels. The CA answers with a certificate that sits under its signature — same public key, same names, now signed. Clients trust that certificate because they already trust the CA. They never see the request.
First principles
A certificate signing request is not a certificate. Generate the private key on the machine that will terminate TLS, or in the HSM or load-balancer that will hold it. Emit the CSR from that key. If the private key travels with the request, the key is burned and you start again.
Three files, three jobs. The key is the secret. The CSR is the request. The certificate is the answer. Browsers and clients never see the CSR. They see the certificate. Read TLS certificates on this desk for what the client actually checks.
Names live in SAN
Modern clients match the host you typed against subjectAltName, not against CN. A CSR whose only name is in CN will get you a certificate that browsers refuse. List every name you need: the apex, www, the API host. A certificate for site.example is not a certificate for www.site.example unless you asked for both.
Make a key, then a CSR
Same OpenSSL path on macOS Terminal, Linux, and Windows if openssl is on the PATH (Git for Windows includes it). Stock macOS ships LibreSSL, which is why the SAN names go in a config file rather than a one-liner flag.
Write a config. Replace the names with yours.
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[req_distinguished_name]
CN = site.example
[v3_req]
subjectAltName = @alt_names
[alt_names]
DNS.1 = site.example
DNS.2 = www.site.exampleThen the key, then the request. Mode 600 on the key. Do not overwrite a live key to issue a CSR.
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out site.key
chmod 600 site.key
openssl req -new -key site.key -out site.csr -config site.cnfSome CAs still demand RSA. Same loop, different key:
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out site.keyInspect before you send
Read the CSR. Confirm the names. Confirm it is a request, not a private key.
openssl req -in site.csr -noout -textYou should see Subject, a public key, and X509v3 Subject Alternative Name with every host you listed. You should not see BEGIN PRIVATE KEY. The file you paste into the CA portal, attach to a ticket, or hand a vendor is site.csr only.
What an admin actually does
- Generate the key on the machine that will terminate TLS, or in the HSM / load-balancer that will hold it. Do not generate it on a laptop and email it in.
- Send the CSR. Never the key. Never a file that begins with BEGIN PRIVATE KEY or BEGIN OPENSSH PRIVATE KEY.
- When the certificate comes back, install it next to the same private key. A cert for a different key is a mismatch. The listener will fail.
- ACME tools (Caddy, certbot, win-acme) mint the CSR for you. You still need this loop for an internal CA, a commercial CA portal, or a vendor that asks you to paste a CSR.
- If the key leaked, stop using it. New key, new CSR, new certificate. Revoke the old one with the CA if they issued it.
Informed by openssl-req(1). Wording is ours.
