1. CSR 基础概念:证书签名请求到底是什么?

各位同学好,我是老赵。今天咱们开始聊 CSR——证书签名请求。这玩意儿是 PKI 体系里最基础、也最容易踩坑的一环。我见过不少运维同学,证书配不上、链断了、浏览器报错,追根溯源,八成是 CSR 生成那一步就埋了雷。

说白了,CSR 就是一份“申请书”。你向 CA 申请一张数字证书,总得告诉人家你是谁、你的公钥是什么、你打算用什么算法签名。这份申请书,就是 CSR。CA 收到后,验证你的身份,然后签发证书给你。

一句话总结:CSR = 公钥 + 身份信息 + 签名,打包发给 CA 换证书。

1.1 CSR 在 PKI 体系中的位置

PKI 体系说白了就是一套“信任传递”的框架。CA 是信任的根,证书是信任的载体。而 CSR,就是整个信任链条的起点。

我画了张图,你看一眼就明白了:

CSR 在 PKI 体系中的位置 CSR 在 PKI 体系中的位置 终端实体 (服务器/客户端/用户) 生成 CSR (公钥 + DN + 签名) CA 审批签发 (验证身份 → 签发证书) 提交申请 发送 CSR 数字证书 (X.509 v3 格式) 签发 安装使用 私钥本地保存 绝不外传

流程其实不复杂:你生成密钥对,私钥自己藏好,公钥塞进 CSR 里,连同你的身份信息一起发给 CA。CA 验证通过后,用它的私钥给你的公钥签个名,证书就出来了。

我的经验:很多新手搞混一件事——CSR 里不包含私钥!私钥一旦泄露,证书就废了。我曾经帮一个客户排查问题,发现他把私钥文件跟 CSR 一起发给了 CA……嗯,那哥们后来被安全主管约谈了。

1.2 CSR 包含的核心字段

一份标准的 CSR(PKCS#10 格式)包含三个核心部分。我习惯把它们叫做“三件套”:

字段 说明 我的备注
公钥 你的 RSA/ECC 公钥,CA 会把它塞进证书里 长度别低于 2048 位,这是底线
DN(Distinguished Name) 你的身份信息,比如域名、公司名、国家 CN 字段最容易填错,我踩过坑
签名算法 你用啥算法给 CSR 签名,证明你持有私钥 SHA-256 起步,SHA-1 已经淘汰了

1.3 公钥:CSR 的核心资产

公钥是 CSR 里最有价值的东西。CA 签发的证书,本质上就是 CA 用它的私钥给你的公钥做了个“背书”。

生成密钥对时,我个人习惯用 RSA 2048 或 ECC P-256。RSA 兼容性好,ECC 性能更优。你想想看,一个 HTTPS 握手,ECC 能省下不少 CPU 周期。

# 生成 RSA 私钥(2048 位)
openssl genrsa -out server.key 2048

# 生成 ECC 私钥(P-256 曲线)
openssl ecparam -genkey -name prime256v1 -out server.key

注意:私钥文件权限一定要锁死。我见过有人把私钥放在 Web 根目录下,结果被爬虫扫到……那画面太美我不敢看。建议 chmod 400 server.key,只有 root 能读。

1.4 DN:你的身份名片

DN 字段决定了证书里会写什么。CA 会根据 DN 来验证你的身份。常见的 DN 字段有这些:

  • CN(Common Name)——通用名称。对于 SSL 证书,这里填域名。比如 www.example.com。我遇到过有人填 IP 地址,结果浏览器报域名不匹配……
  • O(Organization)——组织名称。公司全称,比如 Example Inc.
  • OU(Organizational Unit)——部门名称。比如 IT Department
  • L(Locality)——城市。比如 Beijing
  • ST(State/Province)——省份。比如 Beijing
  • C(Country)——国家代码。两位字母,比如 CN

生成 CSR 时,OpenSSL 会交互式地让你填这些信息。你也可以用 -subj 参数一步到位:

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

避坑指南:我曾经帮一个电商平台排查证书问题,发现他们把 CN 填成了 example.com,但用户访问的是 www.example.com。浏览器直接弹安全警告。记住:CN 必须跟用户实际访问的域名完全一致。通配符证书用 *.example.com。

1.5 签名算法:证明你持有私钥

CSR 里最后一部分是签名。你用私钥给整个 CSR 内容签个名,CA 收到后用 CSR 里的公钥验签。验签通过,就证明你确实持有对应的私钥。

签名算法通常跟公钥算法配套:

  • RSA 密钥 → 用 sha256WithRSAEncryption
  • ECC 密钥 → 用 ecdsa-with-SHA256

为什么不用 SHA-1?因为 SHA-1 已经被证明有碰撞风险。2017 年 Google 就成功做出了 SHA-1 碰撞。现在主流浏览器都已经拒绝 SHA-1 签名的证书了。

# 查看 CSR 的签名算法
openssl req -in server.csr -noout -text | grep "Signature Algorithm"

输出应该是类似 sha256WithRSAEncryption 这样的。如果是 sha1WithRSAEncryption,我建议你重新生成。

1.6 一个完整的 CSR 生成示例

咱们把上面讲的串起来,走一遍完整流程:

# 1. 生成私钥
openssl genrsa -out mydomain.key 2048

# 2. 生成 CSR
openssl req -new -key mydomain.key -out mydomain.csr \
  -subj "/C=CN/ST=Guangdong/L=Shenzhen/O=My Company/OU=DevOps/CN=api.mydomain.com"

# 3. 查看 CSR 内容
openssl req -in mydomain.csr -noout -text

第三步会输出 CSR 的详细信息,包括公钥、DN、签名算法等。你可以逐项核对,确保没填错。

核心原则:私钥不出服务器,CSR 随便发。CA 只需要你的公钥和身份信息,不需要你的私钥。如果有人问你要私钥文件,直接拉黑。