3、证书申请阶段(CSR生成):CSR结构解析、私钥生成策略、常见CSR生成错误及排查
证书申请阶段,说白了就是向CA证明“我是谁”的过程。而CSR(证书签名请求)就是这个阶段的核心产物。我见过不少运维同事,在生成CSR这一步就栽了跟头,后面所有流程全卡住。今天咱们就把CSR的结构、私钥生成策略,以及那些常见的坑,一次性说清楚。
核心观点:CSR的质量直接决定证书能否顺利签发。私钥是CSR的“灵魂”,一旦私钥生成策略出错,后面再怎么折腾也是白费。
3.1 CSR结构解析:CA到底在看什么?
CSR本质上是一个PKCS#10格式的请求体,里面包含了申请者的身份信息和公钥。CA拿到CSR后,会验证里面的签名,确认这个请求确实是由私钥持有者发起的。
一个标准的CSR包含以下核心字段:
| 字段 | 说明 | 常见问题 |
|---|---|---|
| Subject | 证书主体的DN(Distinguished Name) | CN与域名不匹配、OU乱填 |
| Public Key | 公钥信息(算法+密钥长度) | 密钥长度不达标、算法过时 |
| Attributes | 可选属性(如SAN扩展请求) | 未包含SAN导致浏览器报错 |
| Signature | 使用私钥对CSR的签名 | 签名算法太弱、签名验证失败 |
我个人习惯在生成CSR后,先用OpenSSL命令检查一下内容,确保字段正确:
openssl req -in mycsr.csr -noout -text
这条命令会输出CSR的完整结构。你重点看Subject和Public Key部分。我记得有一次,同事生成的CSR里CN写成了IP地址,结果CA直接拒了——因为公共CA基本不接受纯IP的证书申请。
小技巧:如果你需要申请多域名证书,务必在CSR生成时通过配置文件指定SAN(Subject Alternative Name)。很多人在这一步漏掉,导致证书签发后只能保护一个域名。
3.2 私钥生成策略:选对算法,少走弯路
私钥是证书的“命根子”。生成策略不对,后面全是隐患。目前主流的私钥算法就三种:RSA、ECC(ECDSA)、Ed25519。我按实际场景给你分析一下。
| 算法 | 密钥长度 | 安全性 | 性能 | 兼容性 |
|---|---|---|---|---|
| RSA | 2048/4096位 | 高(2048位以上) | 中等 | 最好(几乎所有设备支持) |
| ECC (P-256) | 256位 | 高(等效RSA 3072) | 快 | 良好(主流浏览器支持) |
| Ed25519 | 256位 | 极高 | 极快 | 一般(老旧设备不支持) |
我个人的建议是:
- 通用场景:选RSA 2048位。兼容性最好,几乎所有设备都能认。
- 高性能场景(如TLS握手频繁):选ECC P-256。密钥小、速度快,而且安全性不输RSA 4096。
- 前沿场景(如内部系统、IoT设备):可以考虑Ed25519。但要注意,有些CA和旧版浏览器不支持。
生成私钥时,还有一个关键点:私钥的权限和存储位置。我曾经遇到过客户把私钥直接放在Web服务器的根目录下,权限还是777——这等于把家门钥匙挂在门外。正确的做法是:
# 生成RSA私钥,设置权限为600
openssl genrsa -out server.key 2048
chmod 600 server.key
警告:绝对不要在生成CSR时使用“无密码”的私钥用于生产环境。虽然OpenSSL默认不加密私钥文件,但你应该在生成后立即用AES-256加密:openssl rsa -in server.key -aes256 -out encrypted.key。当然,如果服务重启需要自动加载,那就得权衡一下——我一般建议用HSM或密钥管理服务来托管。
3.3 常见CSR生成错误及排查
这部分是我最想跟你分享的。这些年排查过的CSR问题,少说也有上百个。我把最常见的几类错误整理出来,你遇到类似情况可以直接对照排查。
3.3.1 Subject字段错误
这是最“低级”但最容易犯的错。比如:
- CN与域名不匹配:申请的是
www.example.com,但CN写成了example.com(不带www)。很多CA会严格校验,导致签发失败。 - OU乱填:有些人在OU字段写“IT Department”,但CA要求必须与营业执照一致。结果证书被驳回。
- 国家代码错误:国家代码必须是两位ISO代码,比如中国是CN,不是CHN。
排查方法:用 openssl req -in csr.csr -noout -subject 查看Subject,逐字段核对。
3.3.2 密钥长度不达标
现在的主流CA基本要求RSA密钥至少2048位。如果你用了1024位,CA会直接拒绝。ECC的话,至少要用P-256。
排查方法:
openssl rsa -in server.key -text -noout | head -5
看输出中的“Private-Key: (2048 bit)”这一行,确认位数。
3.3.3 签名算法太弱
有些旧版OpenSSL默认使用SHA-1签名算法。但SHA-1已经被业界淘汰了。CA收到SHA-1签名的CSR,大概率会拒绝。
解决方案:生成CSR时明确指定签名算法:
openssl req -new -key server.key -out server.csr -sha256
重点:从OpenSSL 1.1.0开始,默认签名算法已经是SHA-256。但如果你还在用老版本(比如CentOS 6自带的OpenSSL 1.0.1),一定要手动加 -sha256 参数。
3.3.4 缺少SAN扩展
这是现代浏览器最“敏感”的问题。从Chrome 58开始,浏览器强制要求证书包含SAN(Subject Alternative Name)字段。如果你生成的CSR里没有SAN,签出来的证书在浏览器里会报“不安全”。
正确做法:使用配置文件生成CSR:
# 创建配置文件 csr.conf
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[req_distinguished_name]
CN = www.example.com
O = Example Inc
C = CN
[v3_req]
keyUsage = keyEncipherment, digitalSignature
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = www.example.com
DNS.2 = example.com
DNS.3 = api.example.com
# 生成CSR
openssl req -new -key server.key -out server.csr -config csr.conf
生成后,用以下命令验证SAN是否包含在内:
openssl req -in server.csr -noout -text | grep -A 1 "X509v3 Subject Alternative Name"
3.3.5 私钥与CSR不匹配
这种情况比较隐蔽。有时候你生成了CSR,但后来不小心换了私钥,或者从别处复制了错误的私钥文件。CA在签发证书时,会用CSR里的公钥去验证签名——如果公钥和私钥不匹配,签名验证就会失败。
排查方法:用OpenSSL比对CSR和私钥的模数(Modulus):
# 查看私钥的模数
openssl rsa -in server.key -noout -modulus | md5sum
# 查看CSR的模数
openssl req -in server.csr -noout -modulus | md5sum
两个md5值必须完全一致。不一致的话,说明私钥和CSR不匹配,需要重新生成。
我的习惯:每次生成CSR后,立刻执行一次模数比对,确认无误后再提交给CA。这一步能避免90%的“证书签发后无法安装”问题。
3.4 CSR生成流程全景图
下面这张图总结了CSR生成的核心流程和关键检查点。你可以把它贴在工位上,每次生成CSR时对照检查。
3.5 我的排查清单
最后,分享一份我平时用的排查清单。每次生成CSR后,按这个清单过一遍,基本不会出问题:
- 私钥检查:密钥长度是否达标?权限是否为600?是否加密存储?
- Subject检查:CN是否与域名一致?OU/O/L/C字段是否填写正确?
- 扩展检查:是否包含SAN?keyUsage和extendedKeyUsage是否设置?
- 签名检查:签名算法是否为SHA-256?
- 一致性检查:私钥和CSR的模数是否匹配?
嗯,CSR生成这块其实不难,但细节特别多。你只要把上面这些点都卡住,证书申请阶段基本不会出幺蛾子。我当年刚入行时,就因为少写了一个SAN字段,被CA驳回三次,后来才长记性——从那以后,每次生成CSR都按清单走一遍,再也没出过类似问题。