4. 证书签名请求(CSR):从生成到提交的完整流程

CSR,说白了就是你去CA那里办证书的「申请书」。你把自己的公钥和身份信息填进去,CA审核通过后签个字,证书就到手了。这个环节看似简单,但我见过太多团队在这里栽跟头——密钥没保存好、Common Name写错、扩展字段漏了,最后证书下来用不了,还得重新走一遍流程。

嗯,咱们今天就把CSR的来龙去脉彻底讲清楚。

4.1 CSR到底长什么样?里面塞了哪些信息?

CSR本质上是一个PKCS#10格式的请求体,用ASN.1编码,然后Base64包一层。你拿OpenSSL看一眼就能明白:

openssl req -in my.csr -noout -text

输出里你会看到这么几块核心内容:

字段 说明 我的经验
Subject 证书持有者的DN(Distinguished Name) CN字段最容易填错,后面细说
Public Key 你的公钥,算法和长度都在这里 RSA 2048起步,4096更稳妥
Attributes 可选扩展,比如SAN、密钥用途 现代浏览器强制要求SAN,别漏了
Signature 用你的私钥对CSR签名,证明你持有私钥 这是防抵赖的关键

Subject里的DN包含这些组件:

  • C (Country) — 两位国家代码,比如CN、US
  • ST (State/Province) — 省份或州
  • L (Locality) — 城市
  • O (Organization) — 公司或组织名称
  • OU (Organizational Unit) — 部门,比如IT部
  • CN (Common Name) — 最关键,域名或服务器名
⚠️ 注意: 从2017年开始,主流浏览器已经不再信任仅依赖CN字段的证书。你必须把域名放到Subject Alternative Names (SAN)里,否则Chrome、Safari会直接报不安全。

4.2 用OpenSSL生成CSR,手把手来一遍

我个人习惯把密钥和CSR分开生成,这样密钥可以单独备份,CSR丢了重新生成就行,不用动密钥。

第一步:生成私钥

openssl genrsa -out server.key 2048

这里有个坑——私钥文件默认权限是644,意味着其他用户也能读。我建议生成后立刻改权限:

chmod 400 server.key

第二步:生成CSR

openssl req -new -key server.key -out server.csr \
  -subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/OU=DevOps/CN=www.example.com"

如果你需要SAN扩展,得用配置文件方式:

openssl req -new -key server.key -out server.csr \
  -config <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:www.example.com,DNS:api.example.com")) \
  -reqexts SAN

我曾经帮一个客户排查证书问题,他们生成的CSR里SAN字段是空的,结果证书下来后所有子域名都报错。折腾了两天,最后发现是OpenSSL版本太老,默认配置没加载SAN扩展。

第三步:验证CSR内容

openssl req -in server.csr -noout -text

检查这几项:

  • 公钥长度是不是2048位以上
  • CN和SAN里的域名对不对
  • 签名算法是不是SHA-256(别用SHA-1,已经不安全了)
💡 小技巧: 我习惯把CSR生成命令写成脚本,每次申请证书直接跑脚本,避免手敲出错。脚本里加上日期戳,方便追溯。

4.3 CSR提交与审核流程

CSR生成后,下一步就是提交给CA。流程大致是这样:

CSR提交流程全景图

CSR 提交流程 ① 生成CSR ② 提交到CA ③ CA验证身份 ④ 验证失败 → 驳回 ④ 验证通过 → 签发 ⑤ 修改后重新提交 ⑤ 下载证书并部署 整个流程从提交到签发,DV证书几分钟,OV/EV证书可能需要1-5个工作日

CA的审核方式取决于证书类型:

证书类型 验证方式 审核时间 我遇到的坑
DV(域名验证) 邮箱验证 / DNS TXT记录 / HTTP文件验证 几分钟到几小时 邮箱没配好,验证邮件收不到
OV(组织验证) 人工审核企业资质 1-3个工作日 公司名称和营业执照不一致被驳回
EV(扩展验证) 严格人工审核,电话回访 3-7个工作日 电话没接到,流程重新走

4.4 避坑指南:我踩过的那些CSR的坑

做这行快十年了,CSR相关的翻车现场我见得太多了。挑几个典型的说说:

🚨 坑一:私钥和CSR不匹配
有人拿A密钥生成CSR,提交后把B密钥当成私钥去配证书。结果证书下来后服务起不来,报错说私钥和证书不匹配。解决办法很简单——生成CSR后立刻把密钥和CSR一起归档,文件名带上同样的标识。
🚨 坑二:Common Name写成了IP地址
有些内部系统用IP访问,CSR的CN直接写了IP。但公共CA一般不支持IP证书(除非你额外申请)。我建议内部PKI自己签,或者用DNS名称,别跟公共CA较劲。
🚨 坑三:SAN字段漏了关键域名
这是最常见的。你申请的是 www.example.com 的证书,但用户访问的是 example.com 或者 m.example.com。没有SAN,这些域名全报错。我每次生成CSR都会列一个域名清单,逐个核对。

4.5 自动化CSR生成的最佳实践

手动生成CSR偶尔做一次还行,但如果你管理几十上百个域名,必须上自动化。我推荐的做法是:

  1. 模板化配置 — 把OpenSSL配置文件和SAN清单做成模板,用变量替换域名
  2. 密钥分级管理 — 生产环境用HSM或密钥管理服务,开发环境用本地文件
  3. CSR审计日志 — 每次生成CSR都记录时间、域名、操作人,方便追溯
  4. 预检脚本 — 提交前自动检查CSR内容,比如公钥长度、SAN完整性
💡 我的习惯: 我会写一个Makefile,里面封装好CSR生成、验证、提交的步骤。团队成员只需要 make csr DOMAIN=example.com,剩下的交给脚本。这样既统一又不容易出错。