什么是证书签名请求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(对象标识符):扩展字段的“身份证”

OIDASN.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 部署真正做到安全、可控、可追溯。