CSR

Oct 16, 2021

目录


简介


CSR 全称 “证书签名请求”(Certificate Signing Request). 本文我们将来详细的学习 CSR 的知识,重点集中在 CSR 所包含的信息,及其意义。

CSR 的作用:

CSR 通常由想要获得 X.509 证书的实体(entity) 创建,然后提交给 CA (Certificate Authority), CA 使用它来为实体创建对应的 X.509 证书.


CSR 组成


CSR 中通常包含三部分:

  • 实体的标识名(Distinguished name)
  • 实体的公钥(public key)
  • 其他有关实体的属性信息

在整个证书体系中,所有格式的证书通常以 ASN.1 的方式编码存储在文件中。

接下来,我们学习一下 CSR 的格式,以及如何使用 ASN.1 进行编码


CertificationRequest


CSR 的所有信息包含在根节点 CertificationRequest 中。 它的格式如下:

 1CertificationRequest ::= SEQUENCE {
 2	certificationRequestInfo CertificationRequestInfo,
 3	signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }},
 4	signature BIT STRING
 5}
 6
 7AlgorithmIdentifier {ALGORITHM:IOSet } ::= SEQUENCE {
 8	algorithm ALGORITHM.&id({IOSet}),
 9	parameters ALGORITHM.&Type({IOSet}{@algorithm}) OPTIONAL
10}
11
12SignatureAlgorithms ALGORITHM ::= {
13	... -- add any locally defined algorithms here -- }
14

由CertificationRequest 的定义可知,它有三个子节点,分别为:

  • certificationRequestInfo: 这个子节点包含了所有关于实体的信息,以及实体想要附带在证书中的属性信息。 这个结构会被签名 (sign)
  • signatureAlgorithm: 这个子节点包含了 certificationRequestInfo 节点进行签名时所使用的签名算法的信息.
  • signature: 这个子节点包含的对 certificationRequestInfo 节点使用 signatureAlgorithm 进行签名,所得到的签名结果
签名过程

上面我们看到,CertificationRequest 中的 certificationRequestInfo 节点被签名,得到 signature 子节点。

签名过程如下:

  • 首先,对 certificationRequestInfo 节点使用 ASN.1 DER 方式进行签名,确保签名过程的输入无二义性 (ASN.1 BER 编码方式得到的结果不唯一,因此使用 DER).
  • 以第一步所得结果作为输入, 使用实体的私钥(private key), 使用 signatureAlgorithm 节点中所描述的签名算法进行签名。 得到的结果,保存在 signature 节点中.

CertificationRequestInfo


接着,我们来看看 CertificationRequestInfo 的结构,这个子节点是 CSR 的核心,包含实体的信息.

 1
 2CertificationRequestInfo ::= SEQUENCE {
 3	version INTEGER { v1(0) } (v1,...),
 4	subject Name,
 5	subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
 6	attributes [0] Attributes{{ CRIAttributes }}
 7}
 8
 9SubjectPublicKeyInfo { ALGORITHM : IOSet} ::= SEQUENCE {
10	algorithm AlgorithmIdentifier {{IOSet}},
11	subjectPublicKey BIT STRING
12}
13
14PKInfoAlgorithms ALGORITHM ::= {
15	... -- add any locally defined algorithms here -- }
16
17Attributes { ATTRIBUTE:IOSet } ::= SET OF Attribute{{ IOSet }}
18
19CRIAttributes ATTRIBUTE ::= {
20	... -- add any locally defined attributes here -- }
21
22Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE {
23	type ATTRIBUTE.&id({IOSet}),
24	values SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{@type})
25}

接下来,我们来逐一描述 CertificationRequestInfo 结构中的各个子节点.

  • version: 版本号。 RFC 中描述,为了和将来新版本的 CSR 规范兼容,这里应该使用 0.
  • subject: 实体的标识名. 这个节点对应于将要生成的 X.509 证书中的 Subject 结构.
  • subjectPublicKeyInfo: 这个节点中包含了实体的公钥信息. (比如,比较常见的是 RSA 公钥, 此时这个此段中包含 RSA 公钥的 ASN.1 编码的结果)
  • attributes: 这个节点包含了一系列属性,这些属性将会被包含在将来生成的 X.509 证书中.

实例


接下来,我们通过一个真实的 CSR 文件来巩固一下上面所学。

我们使用 openssl 来创建一个测试 CSR 文件,命令如下:

1openssl req -newkey rsa:2048 -keyout PRIVATEKEY.key -out MYCSR.csr

MYCSR.csr 文件内容如下:

-----BEGIN CERTIFICATE REQUEST-----
MIIC+jCCAeICAQAwgYoxCzAJBgNVBAYTAkNOMRAwDgYDVQQIDAdTaGFhbnhpMQ0w
CwYDVQQHDARYaWFuMRQwEgYDVQQKDAtUZXN0T3JnTmFtZTEVMBMGA1UECwwMVGVz
dFVuaXROYW1lMQ8wDQYDVQQDDAZUZXN0Q04xHDAaBgkqhkiG9w0BCQEWDXRlc3RA
dGVzdC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC5RhgkWN2X
emYjdCR6RLyZjB/WnbafGLzQGuiob9oO89cG2mjL00al19OAPXm/xK9gBwKqO9b+
0QZNFjE81Txo1uxMxs/zILbmVwqISeGESzOi3MOIKCUv/+Zyitrprd9hdSk1Dtny
fS79Nbdd3tkBuVPjIFxay/2fnTv7u4tDDHnfTl1l53Zq+TLRACVtprY45krM/cx4
vhYbjwtZyCtrq1yMZl4QiJCnw1Lcg4jbwjl9tPhziD2ECJErlo5Nhy2u7bFvVXw8
J9L0FhNn9TjJsFa7IXajS4/5VHvmGPBaJMyPSQKiqDhzwi7WjowuV8/X7j/5u8Ei
jUqg7IFIlUblAgMBAAGgKjATBgkqhkiG9w0BCQIxBgwEdGVzdDATBgkqhkiG9w0B
CQcxBgwEdGVzdDANBgkqhkiG9w0BAQsFAAOCAQEAZVHb37v0+iERaXUC2ARncSRa
fTN3m9nHz5UMQVObye98PFIKTPWTyFSZoh0YHQVarIE8lbl1sXSnKIv7xUqaDz1r
8H6Tr3eoy3RpOifU3jC+8GSId/1xgAAzFWhoW6Y/s5X4NdQV1n6OnLr0FGuza0HZ
O2tkXieo+df8P0bbON5AFNQlRztxFm2/t/wkzAl7jT3Olp7oTxCmonZKH8Zb/uIW
7ObYExumz21EpsVawZ38Lqcz6atbZe8O0SHFyZwndzzW0xI4Ulq6n4+lvL3ArDiy
sHQ74wSVAvZPFqdRz3ObfHBuqYyjcNKo4NuxOsFUhQbN1Tffw+w42iRyp8XbKw==
-----END CERTIFICATE REQUEST-----

因为本篇文章,我们不是学习 ASN.1 编码规则,我们不再阐述如何解码, 我们借助工具来看看他的内容。

csr example 1

CSR 的主要结构已经在上图中进行了简要的标注. 我们简单的总结一下:

  • 根节点是 CertificationRequest 结构
  • 根节点下包含了三个子节点,分别为: CertificationRequestInfo, AlgorithmIdentifier, Sigature
  • CertificationRequestInfo 节点中包含了CSR的版本号,请求签名的实体的 Subject 信息,和请求的签名算法,以及实体的额外的属性
  • 版本号为 0,这里是规定的,没有特殊意义
  • Subject 信息是将要创建的 X.509 证书中将要使用的,他是证书中除了公钥之外,最重要的信息。 更多信息,我们在 X509 证书的文章中讲述
  • SubjectPublicKeyInfo 中包含了当前实体想要想要在创建出来的 X.509 证书中使用的公钥。 从上图中,我们看到,是一个 key 长度为 2048 的 RSA 公钥,其中 BIT STRING 节点中包含了对应的公钥参数
  • attributes 包含额外的属性
  • AlgorithmIdentifier 中指定了 Signature 节点中的签名计算时使用的签名算法

疑问?


  1. CSR 中包含实体的私钥吗?

    CSR 中不包含实体的私钥证书。 私钥是永远不会出示给任何其他实体的,应当谨慎保存。 但是创建 CSR 时需要使用实体的私钥对 CSR 中 CertifiationRequestInfo 节点进行签名。 另外,CSR 中需要包含实体的公钥信息(放在 CertificationRequestInfo 的子节点 SubjectPublicKeyInfo 节点中)。


END!!!


Tags