4. 证书申请与CSR生成:密钥对生成、CSR结构、主题字段填写规范
证书申请这件事,说白了就是向CA证明「我是谁」。而CSR(Certificate Signing Request)就是那张申请书。我见过太多人栽在CSR生成这一步——不是密钥没保护好,就是主题字段填错了。今天咱们就把这块掰开揉碎讲清楚。
4.1 密钥对生成:根基不牢,地动山摇
密钥对是证书的根基。私钥一旦泄露,证书就形同虚设。公钥则要嵌入CSR,交给CA签名。
4.1.1 算法选择
目前主流算法就两个阵营:RSA和ECC。我个人习惯这样选:
| 算法 | 推荐位数/曲线 | 适用场景 | 我的建议 |
|---|---|---|---|
| RSA | 2048位(最低)、4096位(推荐) | 通用场景、兼容性要求高 | 大部分企业用这个,稳 |
| ECC | P-256(prime256v1)、P-384 | 移动端、IoT、性能敏感场景 | 密钥小、速度快,但兼容性略差 |
| SM2 | 国密标准曲线 | 国内合规场景 | 政务、金融必选,别搞错了 |
⚠️ 避坑指南: 我曾经见过有人用RSA 1024位生成CSR,结果CA直接拒收。现在1024位已经被各大CA拉黑了。记住:RSA至少2048,能上4096就别省那点计算时间。
4.1.2 生成命令实战
嗯,这里直接上命令。我习惯用OpenSSL,它几乎能搞定一切。
RSA密钥对生成:
# 生成RSA私钥(2048位)
openssl genrsa -out server.key 2048
# 从私钥提取公钥
openssl rsa -in server.key -pubout -out server.pub
# 查看私钥信息
openssl rsa -in server.key -text -noout
ECC密钥对生成:
# 生成ECC私钥(P-256曲线)
openssl ecparam -genkey -name prime256v1 -out ecdsa.key
# 查看曲线列表
openssl ecparam -list_curves
# 从私钥提取公钥
openssl ec -in ecdsa.key -pubout -out ecdsa.pub
💡 我的习惯: 生成私钥后,我第一件事就是改权限——
chmod 400 server.key。私钥文件权限必须严格限制,否则就是给自己挖坑。
4.2 CSR结构:CA到底在看什么?
CSR本质上是一个PKCS#10格式的请求体。你想想看,CA拿到你的CSR后,会验证三件事:
- 公钥是否与私钥匹配——CSR里包含公钥,CA会验证签名
- 身份信息是否完整——主题字段填得对不对
- 签名是否有效——用你的私钥签名的,别人伪造不了
CSR的结构大致如下:
CertificateRequest ::= SEQUENCE {
certificationRequestInfo SEQUENCE {
version INTEGER { v1(0) },
subject Name, -- 主题信息
subjectPKInfo SubjectPublicKeyInfo, -- 公钥信息
attributes [0] Attributes OPTIONAL -- 扩展属性
},
signatureAlgorithm AlgorithmIdentifier,
signature BIT STRING -- 私钥签名
}
说白了,CSR就是「公钥 + 身份信息 + 你的签名」打包在一起。CA拿到后,用你的公钥验一下签名,确认是你本人提交的,然后才开始审核身份。
4.3 主题字段填写规范:细节决定成败
主题字段(Subject)是CSR里最容易被填错的部分。我处理过的证书事故里,至少有三成是因为主题字段不规范导致的。
4.3.1 标准字段一览
| 字段 | 含义 | 必填? | 填写规范 |
|---|---|---|---|
| CN | 通用名称 | 是 | 域名(如 example.com)或个人姓名 |
| O | 组织名称 | 企业证书必填 | 营业执照上的全称,别用缩写 |
| OU | 组织单位 | 否 | 部门名称,如 IT 部、研发中心 |
| L | 所在城市 | 企业证书必填 | 拼音或英文,如 Beijing |
| ST | 所在省份 | 企业证书必填 | 拼音或英文,如 Beijing |
| C | 国家代码 | 是 | 两位ISO代码,如 CN、US |
| emailAddress | 联系邮箱 | 否 | 管理员邮箱,部分CA要求 |
🔑 核心原则: CN字段必须与最终使用证书的域名完全一致。多域名证书用SAN(Subject Alternative Name),CN填主域名即可。我曾经见过有人把CN填成IP地址,结果浏览器直接报安全警告。
4.3.2 常见填法示例
单域名证书:
openssl req -new -key server.key -out server.csr \
-subj "/C=CN/ST=Beijing/L=Beijing/O=Example Inc./OU=IT Dept/CN=www.example.com"
通配符证书:
openssl req -new -key wildcard.key -out wildcard.csr \
-subj "/C=CN/ST=Shanghai/L=Shanghai/O=Example Inc./CN=*.example.com"
⚠️ 避坑指南: 我曾经遇到一个客户,把CN填成了「example.com」,但实际用的是「www.example.com」。证书签发后,浏览器提示域名不匹配,只能重新申请。记住:CN必须精确匹配,多一个www都不行。
4.3.3 交互式生成CSR
如果你不想用-subj参数,也可以用交互模式:
openssl req -new -key server.key -out server.csr
# 然后按提示填写:
# Country Name (2 letter code) [AU]: CN
# State or Province Name (full name) [Some-State]: Beijing
# Locality Name (eg, city) []: Beijing
# Organization Name (eg, company) [Internet Widgits Pty Ltd]: Example Inc.
# Organizational Unit Name (eg, section) []: IT Dept
# Common Name (e.g. server FQDN or YOUR name) []: www.example.com
# Email Address []: admin@example.com
嗯,这里要注意:交互模式下,有些字段可以留空,但CN必须填。另外,密码(challenge password)那项建议留空,除非CA明确要求。填了反而麻烦——每次操作证书都要输密码。
4.4 知识体系总览
下面这张图把本章的核心逻辑串起来了。你一看就明白:
4.5 验证CSR:别等提交了才发现问题
生成CSR后,我建议你马上验证一下。别等提交给CA了才发现填错了,那多尴尬。
# 查看CSR内容
openssl req -in server.csr -text -noout
# 验证私钥与CSR是否匹配
openssl rsa -in server.key -noout -modulus | openssl md5
openssl req -in server.csr -noout -modulus | openssl md5
# 两个md5值一致,说明匹配
💡 我的习惯: 每次生成CSR后,我都会用上面两条命令做一次「私钥-CSR匹配校验」。别嫌麻烦,这一步能避免至少一半的证书申请事故。
好了,密钥对生成、CSR结构、主题字段规范,这三块你掌握了吗?说白了,证书申请就是「生成密钥 → 组装CSR → 提交CA」三步走。每一步都有坑,但只要你按规范来,基本不会出问题。