3、证书申请与CSR:密钥对、签名请求与验证流程
证书申请这件事,说白了就是向CA证明“我是谁,我拥有什么”。而CSR(Certificate Signing Request)就是这个证明的载体。我见过不少运维同学,一把openssl req -new敲下去就完事了,结果证书签发回来发现组织名写错、域名漏了——嗯,这种坑我踩过不止一次。
这一章,我们就把CSR的生成、解析和验证掰开揉碎讲清楚。
3.1 生成密钥对:一切信任的根基
证书的核心是公钥,而公钥必须对应一个私钥。私钥丢了,证书就是一张废纸。所以第一步,先把密钥对生成好。
3.1.1 选择算法与密钥长度
目前主流的选择就两个:
| 算法 | 推荐密钥长度 | 典型场景 |
|---|---|---|
| RSA | 2048 或 4096 位 | 通用、兼容性最好 |
| ECDSA | P-256 或 P-384 | 性能敏感、IoT、移动端 |
我个人习惯:服务器证书用 RSA 2048,兼容性无坑;内部系统或新项目优先上 ECDSA P-256,性能更好,密钥也短。
3.1.2 生成私钥的命令
RSA私钥生成:
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out server.key
ECDSA私钥生成:
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:prime256v1 -out server.key
生成后,务必检查私钥权限:
chmod 400 server.key
私钥文件权限设为400,只有属主能读。这是底线。
3.2 创建证书签名请求(CSR)
有了私钥,下一步就是生成CSR。CSR里包含你的公钥和身份信息,然后交给CA去签名。
3.2.1 交互式生成CSR
openssl req -new -key server.key -out server.csr
执行后会让你填一堆字段。很多人在这里随便填,结果证书下来发现不能用。我建议你提前准备好配置文件。
3.2.2 使用配置文件生成CSR(推荐)
写一个server.cnf:
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
req_extensions = req_ext
[dn]
C = CN
ST = Beijing
L = Beijing
O = Example Inc.
OU = IT
CN = www.example.com
[req_ext]
subjectAltName = DNS:www.example.com, DNS:example.com
然后一行命令搞定:
openssl req -new -key server.key -out server.csr -config server.cnf
这样生成的CSR,字段统一、不易出错,适合批量操作。
3.3 CSR字段解析:每一行都有意义
CSR不是纯文本,它是ASN.1编码的。但我们可以用openssl把它解析成可读格式:
openssl req -in server.csr -noout -text
输出大致长这样:
Certificate Request:
Data:
Version: 1 (0x0)
Subject: C = CN, ST = Beijing, O = Example Inc., CN = www.example.com
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:xx:xx:xx...
Attributes:
(none)
Requested Extensions:
X509v3 Subject Alternative Name:
DNS:www.example.com, DNS:example.com
Signature Algorithm: ecdsa-with-SHA256
Signature Value:
30:xx:xx:xx...
关键字段说明:
| 字段 | 含义 | 常见错误 |
|---|---|---|
| Subject | 证书持有者的身份信息 | 组织名(O)与营业执照不一致 |
| Public Key | 你的公钥,CA会签入证书 | 算法或长度不符合CA要求 |
| Subject Alternative Name | 证书保护的域名/IP列表 | 遗漏二级域名或IP |
| Signature | 用私钥对CSR的签名,证明你拥有私钥 | 签名算法过弱(如SHA1) |
这里有个细节:CSR里的签名,是用你的私钥对CSR自身做的签名。CA收到CSR后,会用CSR里的公钥验这个签名。验不过?说明你根本不拥有对应的私钥,CA直接拒绝。
3.4 CSR验证流程:别等CA退回来才后悔
CSR提交给CA之前,自己先验一遍。我习惯三步走:
3.4.1 验证CSR格式与完整性
openssl req -in server.csr -noout -verify
输出verify OK才算通过。如果报错,检查文件是否损坏或编码格式是否正确。
3.4.2 核对CSR内容
用-text查看字段,逐项确认:
- 国家代码(C)是不是两位大写字母?
- 组织名(O)有没有拼写错误?
- 通用名称(CN)是不是主域名?
- SAN里有没有遗漏?
我曾经帮一个客户排查问题,折腾了两天,最后发现CSR里组织名多了一个空格。CA系统严格匹配,一个空格就导致审核失败。
3.4.3 验证公钥与私钥是否匹配
这一步很多人忽略。先提取CSR里的公钥:
openssl req -in server.csr -noout -pubkey > csr_pub.pem
再提取私钥对应的公钥:
openssl pkey -in server.key -pubout > key_pub.pem
然后比对:
diff csr_pub.pem key_pub.pem
没有输出,说明匹配。有差异?那你可能拿错了私钥,或者CSR是用别的密钥生成的。
3.5 知识体系:CSR生命周期全景
下面这张图,把CSR从生成到提交的完整流程串起来了。
这张图把CSR的生成、创建、验证和提交决策串成了一个闭环。你想想看,如果每次生成CSR都按这个流程走一遍,还会出那些低级错误吗?
3.6 本章小结
CSR是证书申请的第一步,也是最重要的一步。密钥对生成要选对算法和长度,CSR字段要填对,提交前一定要自己验一遍。我见过太多因为CSR问题导致证书签发失败或安全告警的案例,说白了,都是细节没到位。