申请 HTTPS 证书时,证书机构通常会让你提交一段以 BEGIN CERTIFICATE REQUEST 开头的内容,这就是 CSR。它看起来只是一大段 Base64,实际里面已经装好了证书主题、公钥、SAN 请求和签名。这里填错一项,证书即使签发成功,也可能不能用于准备部署的域名。

真正需要保管的不是 CSR,而是生成 CSR 时同时产生的私钥。CSR 可以发给证书机构,私钥不能发给任何人。签发后的证书只含公钥,丢失私钥以后无法从证书或 CSR 里恢复,只能重新生成、重新验证域名并重新签发。

先分清会拿到的几个文件#

一次完整操作通常会出现四种内容:

  • 私钥:常见头部是 BEGIN PRIVATE KEY,只能留在自己控制的环境。
  • CSR:头部是 BEGIN CERTIFICATE REQUEST,提交给 CA。
  • 公钥:头部是 BEGIN PUBLIC KEY,可用于核对密钥或其他公开用途。
  • 签发证书:头部是 BEGIN CERTIFICATE,由 CA 返回,部署时和原私钥配对。

CSR 的签名可以证明提交者持有对应私钥,并保证请求内容没有在中途被改掉。它不能证明你拥有某个域名,也不会自动获得证书。域名控制权仍要通过 DNS、HTTP 文件或 CA 提供的其他方式完成验证。

CN 和 SAN 应该怎样填写#

CN 是主题中的 Common Name。申请单域名证书时,一般填主要域名,例如:

text已剪下 ✓
example.com

但现代浏览器真正用来匹配主机名的是 SAN,也就是 Subject Alternative Name。只填写 CN 而没有 SAN,是很多旧教程留下的问题。要同时使用裸域和 www,SAN 至少应包含:

text已剪下 ✓
DNS:example.com
DNS:www.example.com

通配符 *.example.com 通常覆盖 www.example.comapi.example.com 这一层,但不覆盖 example.com,也不覆盖 a.b.example.com。裸域与通配符都要用,就把两项都写进去。

IP 地址不能伪装成 DNS 名称,应写成 IP:203.0.113.10。内部系统若使用单标签主机名,也要先确认自己的私有 CA 和客户端策略允许;公共 CA 通常不会按内部名称签发公开信任证书。

在浏览器里生成一份 CSR#

可以打开 CSR 证书请求生成器,按下面的顺序填写:

  1. 在 CN 填主要域名,不要带 https://、路径或端口。
  2. 组织、部门、城市按签发要求填写;国家代码使用 CNUS 这种两位字母。
  3. 在 SAN 区每行填写一个域名、IP、邮箱或 URI。页面默认会把有效域名 CN 也加入 DNS SAN。
  4. 选择 RSA 长度。没有明确合规要求时,2048 bit 是常见实用基线;更长密钥会增加生成和握手成本。
  5. 点击生成。工具会重新解析生成结果,验证 CSR 签名,并显示 Subject、SAN、公钥算法与 SPKI SHA-256 指纹。
  6. 分开保存 CSR 与私钥。提交 CSR,不提交私钥。

页面使用浏览器 Web Crypto 生成密钥,CSR 编码、签名和 ZIP 都在本机完成。不过“没有上传”不等于私钥天然安全:下载目录可能被云盘同步,剪贴板可能有历史记录,屏幕共享也可能把内容录进去。正式服务器证书更稳妥的做法,仍是在最终部署环境或 KMS、HSM 中生成私钥,尽量不搬运。

用 OpenSSL 再检查一次#

拿到 example.com.csr.pem 后,可以在装有 OpenSSL 的机器上查看并验证:

bash已剪下 ✓
openssl req -in example.com.csr.pem -noout -text -verify

输出里重点核对:

  • Subject 是否写对组织和 CN。
  • Subject Alternative Name 是否完整。
  • Public Key Algorithm 与密钥长度是否符合要求。
  • Signature Algorithm 是否为预期算法。
  • 最后是否显示请求签名验证成功。

如果 CA 提示 CSR 无效,不要先反复复制粘贴。先检查 PEM 头尾有没有丢失、正文是否被插入空格、提交框是否要求去掉头尾,以及目标 CA 是否只接受特定密钥类型。

签发后一定要比对公钥#

证书签发成功并不表示文件一定拿对。多台服务器、多个终端窗口同时操作时,最常见的麻烦之一,是 CSR 由 A 私钥生成,部署时却拿了 B 私钥。

可把私钥导出公钥,再比较两边指纹。也可以用页面生成时显示的 SPKI SHA-256 指纹作为交付记录。若证书与私钥不配对,Web 服务器通常会在加载配置时直接报错;有些面板只给出模糊的“证书格式错误”。

拿到 CA 返回的 CRT 或 PEM 后,再用 SSL 证书解析器 检查:

  • SAN 是否与申请清单一致。
  • 有效期是否正确。
  • Key Usage 与 Extended Key Usage 是否允许 TLS 服务端认证。
  • 公钥长度和 SHA-256 指纹是否与 CSR 对应。
  • CA 是否同时提供了需要部署的中间证书。

如果只是需要一对用于接口加密或签名的测试密钥,不一定需要 CSR,可以直接使用 RSA 密钥生成器 选择 RSA-OAEP、RSA-PSS 或 PKCS#1 v1.5。证书请求则固定使用签名密钥来证明持有私钥,两种工作不要混在一起。

最容易返工的五种情况#

第一,只看 CN,没有检查 SAN。证书签出来以后,浏览器仍报域名不匹配。

第二,申请 *.example.com 后以为它也覆盖裸域。实际部署到 example.com 时仍缺一个名称。

第三,重新生成 CSR,却继续使用旧私钥。每次生成新 CSR 通常都会产生一把新私钥,文件必须成对保存。

第四,把包含私钥的 ZIP 发给证书机构或上传工单。CA 只需要 CSR;一旦私钥离开控制范围,应停止使用并重新生成。

第五,只在面板里看到“已签发”就结束。CDN、负载均衡、源站和不同 SNI 入口可能仍返回旧证书,最终还要从真实域名做握手检查。

CSR 本身不复杂,麻烦都在文件关系和名称边界。把 SAN 列清楚、把私钥单独保管、记录公钥指纹,并在签发后核对证书和实际部署,基本就能避开大多数重复申请。