原文同时发布于本人个人博客: https//kutank.com/blog/cert-csr/
简介
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 中。 它的格式如下:
CertificationRequest ::= SEQUENCE {certificationRequestInfo CertificationRequestInfo,signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }},signature BIT STRING
}AlgorithmIdentifier {ALGORITHM:IOSet } ::= SEQUENCE {algorithm ALGORITHM.&id({IOSet}),parameters ALGORITHM.&Type({IOSet}{@algorithm}) OPTIONAL
}SignatureAlgorithms ALGORITHM ::= {... -- add any locally defined algorithms here -- }
由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 的核心,包含实体的信息.
CertificationRequestInfo ::= SEQUENCE {version INTEGER { v1(0) } (v1,...),subject Name,subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }},attributes [0] Attributes{{ CRIAttributes }}
}SubjectPublicKeyInfo { ALGORITHM : IOSet} ::= SEQUENCE {algorithm AlgorithmIdentifier {{IOSet}},subjectPublicKey BIT STRING
}PKInfoAlgorithms ALGORITHM ::= {... -- add any locally defined algorithms here -- }Attributes { ATTRIBUTE:IOSet } ::= SET OF Attribute{{ IOSet }}CRIAttributes ATTRIBUTE ::= {... -- add any locally defined attributes here -- }Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE {type ATTRIBUTE.&id({IOSet}),values SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{@type})
}
接下来,我们来逐一描述 CertificationRequestInfo 结构中的各个子节点.
- version: 版本号。 RFC 中描述,为了和将来新版本的 CSR 规范兼容,这里应该使用 0.
- subject: 实体的标识名. 这个节点对应于将要生成的 X.509 证书中的 Subject 结构.
- subjectPublicKeyInfo: 这个节点中包含了实体的公钥信息. (比如,比较常见的是 RSA 公钥, 此时这个此段中包含 RSA 公钥的 ASN.1 编码的结果)
- attributes: 这个节点包含了一系列属性,这些属性将会被包含在将来生成的 X.509 证书中.
实例
接下来,我们通过一个真实的 CSR 文件来巩固一下上面所学。
我们使用 openssl 来创建一个测试 CSR 文件,命令如下:
openssl 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 的主要结构已经在上图中进行了简要的标注. 我们简单的总结一下:
- 根节点是 CertificationRequest 结构
- 根节点下包含了三个子节点,分别为: CertificationRequestInfo, AlgorithmIdentifier, Sigature
- CertificationRequestInfo 节点中包含了CSR的版本号,请求签名的实体的 Subject 信息,和请求的签名算法,以及实体的额外的属性
- 版本号为 0,这里是规定的,没有特殊意义
- Subject 信息是将要创建的 X.509 证书中将要使用的,他是证书中除了公钥之外,最重要的信息。 更多信息,我们在 X509 证书的文章中讲述
- SubjectPublicKeyInfo 中包含了当前实体想要想要在创建出来的 X.509 证书中使用的公钥。 从上图中,我们看到,是一个 key 长度为 2048 的 RSA 公钥,其中 BIT STRING 节点中包含了对应的公钥参数
- attributes 包含额外的属性
- AlgorithmIdentifier 中指定了 Signature 节点中的签名计算时使用的签名算法
疑问?
-
CSR 中包含实体的私钥吗?
CSR 中不包含实体的私钥证书。 私钥是永远不会出示给任何其他实体的,应当谨慎保存。 但是创建 CSR 时需要使用实体的私钥对 CSR 中 CertifiationRequestInfo 节点进行签名。 另外,CSR 中需要包含实体的公钥信息(放在 CertificationRequestInfo 的子节点 SubjectPublicKeyInfo 节点中)。
END!!!