什么是证书签名请求CRS(Certificate Signing Request)
证书签名请求CRS是一段经过 ASN.1 编码的结构化数据,包含你的域名、公钥信息和身份标识,却绝不包含私钥。
本文将深度拆解 CSR 的内部结构,剖析 ASN.1 编码中的公钥与识别名(DN),揭秘 OID(对象标识符)如何定义扩展字段。掌握CRS的内部结构,才能明白如何使用安全的方式申请SSL/TSL证书,也能轻松排查 CSR 导致的签发失败问题。
证书签名请求 CSR 的本质:只发送“签发请求”,不发送“私钥”
1. 证书签名请求CSR 严格遵循 PKCS#10 标准(RFC 2986),本质是一条“签名后的请求”。
2. SSL证书签发的整个过程中,私钥处于“安全模式”,杜绝中间人劫持风险。
3. CSR 通常以 PEM 格式呈现(以 -----BEGIN CERTIFICATE REQUEST----- 开头),实际是 Base64 编码的 ASN.1 二进制结构。
证书签名请求CRS核心逻辑
- 本地生成私钥 ,使用私钥对 CSR 信息签名 , 只把 CSR(含公钥 + 签名)发给 CA。
- CA 用 CSR 中的公钥验证签名后,用自己的中间证书私钥签发正式证书。
证书 PEM 解码后,包含三个顶级字段:
- certificationRequestInfo(请求主体)
- signatureAlgorithm(签名算法)
- signature(签名值)
ASN.1 结构详解:公钥信息与识别名(DN)
证书签名请求 CSR 的骨架是 ASN.1(Abstract Syntax Notation One),一种严格的树状数据描述语言。整个结构用 DER(Distinguished Encoding Rules)编码,保证全球解析一致。
CRS 顶层结构(CertificationRequest)
CertificationRequest ::= SEQUENCE {
certificationRequestInfo CertificationRequestInfo,
signatureAlgorithm AlgorithmIdentifier,
signature BIT STRING
}
CRS 核心部分(certificationRequestInfo)
CertificationRequestInfo ::= SEQUENCE {
version INTEGER { v1(0) }, -- 几乎永远是 0
subject Name, -- 识别名 DN
subjectPKInfo SubjectPublicKeyInfo, -- 公钥信息
attributes [0] IMPLICIT Attributes OPTIONAL -- 扩展字段
}
CRS 识别名(Subject DN)
DN 是证书的“身份证信息”,用 RDN(Relative Distinguished Name)序列组成。身份证信息 DN 常见字段
* CN(Common Name):域名,如 example.com 或 \*.example.com
* O(Organization):组织名称
* OU(Organizational Unit):部门
* L(Locality):城市
* ST(State):省份
* C(Country):国家代码(2 位字母)
CRS 公钥信息(SubjectPublicKeyInfo)
公钥信息是 CSR 最关键的部分,证明“你拥有对应的私钥”:
SubjectPublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier,
subjectPublicKey BIT STRING
}
- algorithm:标识公钥类型,如 RSA(OID 1.2.840.113549.1.1.1)或 EC(OID 1.2.840.10045.2.1)。
- subjectPublicKey:实际公钥比特串(RSA 是模数+指数,ECC 是曲线点)。
- CA 验证签名时,正是用这个公钥解开 signature 字段,从而确认请求未被篡改。
Attributes(可选扩展属性)
现代证书签名请求 CSR 几乎都会带扩展请求(extensionRequest),把 SAN(Subject Alternative Name)、Key Usage 等信息塞进去,避免 CA 默认只签 CN。
OID(对象标识符):扩展字段的“身份证”
OID 是 ASN.1 世界的“全球唯一编号”,像互联网的 IP 地址一样,由 IANA 和 ISO 管理。CSR 中所有可扩展字段都通过 OID 标识,避免歧义。
关键 OID 示例
1.2.840.113549.1.9.14: extensionRequest(扩展请求容器)
- 2.5.29.17: subjectAltName(支持多域名、泛域名)
- 2.5.29.15: keyUsage(数字签名、密钥加密等)
- 2.5.29.19: 任basicConstraints(是否 CA 证书)
- 2.5.29.37: extendedKeyUsage(服务器认证、客户端认证)
例如:生成泛域名 CSR 时,会自动在 attributes 中塞入 subjectAltName 的 OID 2.5.29.17,并填入 *.example.com 和 example.com。CA 看到这个 OID 后,就知道要签通配符证书。 OID 让 CSR 变得“自我描述”,即使 CA 服务器不认识某个扩展,也能安全忽略,而不会误解 CRS 结构。
验证技巧:使用解析工具校验 CSR
使用 openssl 解析工具虽然强大,但对普通开发者不够友好。CertificateHub 提供了免费的 CSR 解析工具),专为“浏览器本地解析CRS”的用户设计。
解析工具输出内容(实时 ASN.1 解码)
- Subject DN:以表格形式展示 CN、O、C 等字段,一目了然是否填错域名。
- 公钥信息:算法(RSA 2048 / ECC P-256)、公钥指纹(SHA-256)、密钥长度。
- 扩展字段:自动展开所有 OID,并给出中文解释(如 “2.5.29.17: subjectAltName = *.example.com, example.com”)。
- 签名验证:自动匹配你本地私钥(可选上传私钥),确认“公私钥配对”。
- 安全性提示:若检测到弱算法(RSA <2048)、缺失 SAN、OID 异常,会红色高亮警告。
工具完全在浏览器端运行(同样基于 Web Crypto),CSR 内容绝不上传服务器。
进阶命令行对比(可选)
openssl req -in your.csr -noout -text
常见问题与最佳实践
- CSR 太大:通常因为 SAN 域名过多(超过 100 个),建议拆分证书。
- 签发失败:90% 是 DN 中 CN 与域名不符,或 extensionRequest 里的 OID 格式错误。
- 泛域名必备:必须在 CSR 中加入 OID 2.5.29.17,否则 Let's Encrypt 只会签单域名。
- 安全建议:永远在浏览器本地生成(CertificateHub、Keygen 等),避免用服务器 openssl(私钥会短暂存在磁盘)。
总结:从 ASN.1 的树状结构到 OID 的全局标识,详细了解 CSR 的“庐山真面目”。CRS 它不是简单的“域名列表”,而是一份经过严密编码、签名保护的“公钥+身份证明”请求。 使用证书解析工具,确保每一条 OID、每一个 DN 字段都正确无误。掌握 CSR 和 从“私钥生成”到“证书签发”全链路的主动权,让 HTTPS 部署真正做到安全、可控、可追溯。