在开放的互联网环境中,通信的双方通常是互不相识,数字签名并不能解决身份认证的问题。比如在数字签名中,私钥签名,公钥验证签名。如果有人冒充给了你公钥,对方持有假冒公钥对应的私钥,这种情况下签名、验签都没问题,但你是在和一个假的通信。退一步说,你开始拿到的确实是发布的公钥,如果有人偷偷替换掉了你的机器上的公钥,这样你实际拥有的是李鬼的公钥,但是还以为这是的公钥。因此,李鬼就可以冒充,用自己的私钥做成"数字签名",写信给你,而你则使用假的公钥进行解密。
在现实生活中,我们通常使用身份证或者护照来证明自己的身份,而在虚拟的网络世界,则需要使用数字证书。
很多人可能听说过 X.509 证书,它实际上就是一种数字证书。数字证书标准有很多,但使用广泛的就是 X.509 标准,以至于现在一般将数字证书等同于X.509证书。
X.509标准
PKI(Public Key Infrastructure,称为公钥基础设施)是一个集合体,由一系列的软件、硬件、组织、个体、法律、流程组成,主要目的就是向客户端提供服务器身份认证。
为了规范化运用PKI技术,出现了很多标准,HTTPS中常用的标准就是X.509标准。X.509标准来自国外电信联盟电信标准(ITU-T)的X.500标准,1995年国外互联网工程任务组(IETF)的PKIX小组成立,用来建设互联网的PKI公钥基础设施标准,建立的标准就是X.509。
互联网大部分应用(比如HTTPS协议、S/MIME邮件协议)使用的证书标准就是X.509标准,该标准可以参考RFC 5280文档。其他的组织也会基于X.509标准构建自己的PKI标准,比如IPsec使用自己的PKI标准,该标准定义在RFC 4945文档。
从中可以看出,PKI涉及的领域比较广泛,是一个相对松散的概念,一般来说,我们重点关注X.509的PKI标准即可。
PKI的组成
根据PKI X.509标准,PKI组成下所示。
PKI的组成
(1)服务器实体(end entity),就是需要申请证书的实体,比如 www.example.com 域名的拥有者可以申请一张证书,证书能够证明 www.example.com 域名所有者的身份。
(2)CA机构,CA是证书签发机构,在审核服务器实体的有效身份后,给其签发证书,证书是用CA机构的密钥对(比如RSA密钥对)对服务器实体证书进行签名。
(3)RA机构,注册机构,主要审核服务器实体的身份,一般情况下,可以认为CA机构包含了RA机构。
(4)证书仓库,CA机构签发的证书全部保存在仓库中,证书也可能过期或者被吊销,CA机构吊销的证书称为证书吊销列表CRL(Certificate Revocation List)。
(5)证书校验方(relying party),校验证书真实性的软件,在Web领域,读者熟悉的证书校验方就是浏览器。在本书中,浏览器、客户端、证书校验方可以认为是同一个概念。为了进行校验,证书校验方必须充分信任第三方CA机构,证书校验方集成了各个CA机构的根证书。
X.509标准的内容
X.509标准包含的内容较广泛,内容如下:
(1)证书的作用,第三方认证机构为服务器实体(end entity)签发证书,证书校验方可以使用证书对服务器实体的身份进行认证。
(2)证书文件的结构,证书是一个文件,理解证书的结构、属性、值较重要。
(3)管理证书,服务器实体(end entity)向CA机构申请证书的流程,CA机构审核服务器实体身份的标准,签发证书的流程。
(4)校验证书,通过严谨的步骤校验证书,或者说校验服务器实体(end entity)身份,涉及两部分内容,一部分是证书签名校验,涉及证书链的概念。另外一部分是校验服务器实体属性,比如证书包含的域名、证书有效期等。
(5)证书的撤销问题,包括CRL和OCSP协议等概念。
证书
证书是PKI中核心的部分,理解了证书等同于理解了PKI的工作原理,证书中包含了很多信息,由签名、服务器实体(end entity)信息、CA机构信息三部分组成。
数字证书可以建立公钥与用户之间的对应关系。数字证书实际上是一种特殊的文件格式,包含用户身份信息、用户公钥和CA私钥的数字签名。数字证书中只包含公钥,并不包括私钥,可以公开。而数字证书中包含CA私钥的签名,所以具有防伪性。
证书是一个文件,用记事本打开,是一堆无意义的数据。理解证书内容必须先明白ASN.1(Abstract Syntax Notation One)的概念。
ASN.1
ASN.1是国外电信联盟电信标准(ITU-T)定义的标准,用来结构化描述证书。ASN.1类似于JSON或者XML这样的数据结构。ASN.1定义了复杂的数据结构,通常现有的加密库都包含了ASN.1的编码与解析,网上也可以找到源码,一般没必要完全理解ASN.1内部结构。我们可以将ASN.1看作一种伪代码,是用来描述证书结构的。
X.509是标准,ASN.1也是标准。X.509标准定义了证书应该包含的内容,而借助ASN.1标准来描述X.509标准(或者说证书),可以让机器和人很好地理解和组织X.509标准。
证书结构
证书的主要结构如下:
Certificate ::= SEQUENCE {
tbsCertificate TBSCertificate,
signatureAlgorithm AlgorithmIdentifier,
signature BIT STRING
}
SEQUENCE是ASN.1中的一个结构体,相当于一个多维数组,数组由多个元素组成,每个元素有一个名称(比如tbsCertificate),名称有对应的属性(比如TBSCertificate),名称的值取决于属性。每个元素还可以嵌套其他的ASN.1结构,比如再嵌套一个SEQUENCE, TBSCertificate结构就是一个SEQUENCE结构。
CA机构对证书进行签名,为了让证书校验方(比如浏览器)进行校验,必须在证书中说明CA机构使用的签名算法。结构中的signatureAlgorithm代表的就是签名算法,signature就是签名值,tbsCertificate就是需要签名的内容,也是证书的核心,包括了服务器实体和CA机构的信息。
接下来看TBSCertificate结构,它是证书内容的核心部分。
TBSCertificate ::= SEQUENCE {
version [0] Version DEFAULT v1,
serialNumber CertificateSerialNumber,
signature AlgorithmIdentifier,
issuer Name,
validity Validty,
subject Name,
subjectPublicKeyInfo SubjectPublicKeyInfo,
issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
-- If present, version MUST be v2 or v3
subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
-- If present, version MUST be v2 or v3
extensions [3] Extensions OPTIONAL
-- If present, version MUST be v3
}
1)version
version表示证书的版本号,目前有3个版本(v1, v2, v3),证书校验方(比如浏览器)根据版本进行校验,如果一个证书是v3版本,而证书校验方使用v1版本标准校验必然是错误的。version的类型是Version,结构定义如下:
Version ::= INTEGER { v1(0), V2(1), V3(2) }
Version类型相当于一个枚举整型,有三个整数值可以选择。
2)serialNumber
每个证书都有的编号,对于不同的CA机构来说,编号是无法预测的,CertificateSerialNumber是一个整型类型。
3)signature
证书是通过签名算法进行签名的,为了让证书校验方(比如浏览器)验证签名,必须告诉其签名算法,签名算法信息也在TBSCertificate结构体中。签名算法包含两个部分,分别是摘要算法和签名算法。对于ECDSAWithSHA256签名算法来说,ECDSA是签名算法,SHA256是摘要算法。接下来了解在ASN.1中是如何定义的AlgorithmIdentifier类型的。
签名算法标识符AlgorithmIdentifier类型本身也是一个SEQUENCE结构,由两个子元素构成:
AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER,
parameters ANY DEFINED BY algorithm OPTIONAL
}
algorithm类型是OBJECT IDENTIFIER(OID),在X.509中是较普遍的一种数据结构,简单地理解就是一个字符数组,在《GM/T 0006-2012 密码应用标识规范》中就为国密规范定义了很多OID。
比如基于SM2算法和SM3算法的签名的OID为 1.2.156.10197.501
4)issuer
代表CA机构的名称,Issuer主要由国家(C)、组织(O)、子组织名(CN)组成
5)validity
CA机构是赢利的组织,证书使用期限越长价格越高,在证书中包括了证书的有效期,证书校验方需要校验证书有效期,如果证书有效期失效,表明证书不能代表服务器实体身份。
6)subject
代表服务器实体的名称,该组织向CA机构申请证书,其对应的Name类型和issuer的Name类型是一样的,CN表示服务器实体的域名(比如CN =www.example.com)。对于Web网站来说,每个网站都有一个域名,证书和域名息息相关,早期证书校验方校验证书的时候是将URL中的域名和证书subject值中的CN比较,如果一致,代表证书校验。随着时间的推移,一张证书可能包含多个域名,所以不再使用CN来校验证书域名了,而使用SAN证书扩展进行域名校验。
7)subjectPublicKeyInfo
服务器实体申请证书的时候,包含的一个重要属性就是服务器公钥,该公钥对应的算法就是公开密钥算法。
subjectPublicKeyInfo包含两部分信息,分别是公开密钥算法和公钥值,其对应的类型就是SubjectPublicKeyInfo类型:
SubjectPublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier,
subjectPublicKey BIT STRING
}
8)issuerUniqueID和subjectUniqueID
这两个分别代表CA机构和服务器实体的编号,目前已经被相应的证书扩展替代。
9)extension
扩展是X.509 V3版本引入的,主要是为了扩展证书的含义,在不改变X.509版本的情况下,可以相对方便地增加证书新属性,新添加的扩展是否生效取决于证书校验方。
通过证书扩展,CA机构和证书校验方可以在不修改(或者较少修改)代码的前提下使用该扩展,前提是双方都认这个扩展。X.509 V3定义了14个扩展,如果需要额外添加扩展,就需要双方都支持。
CSR
CSR是Certificate Signing Request的缩写,服务器实体为了证明自己的身份,需要向CA机构申请证书,在申请证书之前,必须先生成一个CSR文件,然后将CSR文件发送给CA机构。
CSR文件包括两部分内容:
生成证书必需的信息,比如域名、公钥。
服务器实体的证明材料,比如企业的纳税编号等信息。
CSR文件采用的标准是PKCS#10,请参考RFC2986。CSR用ASN.1标准描述,整体结构如下:
CertificationRequest ::= SEQUENCE {
certificationRequestInfo CertificationRequestInfo,
signatureAlgorithm AlgorithmIdentifier,
signature BIT STRING
}
该结构包含两部分:
certificationRequestInfo结构表示证书的请求信息。
签名信息,对certificationRequestInfo的签名。
CertificationRequestInfo的信息需要重点关注,其结构如下:
CertificationRequestInfo ::= SEQUENCE {
version INTEGER { v1(0) } (v1, ...),
subject Name,
subjectPKInfo SubjectPublicKeyInfo,
attributes [0] Attributes
}
version表示PKCS#10标准的版本号。
subject表示服务器主体的可分辨名称DN,重要的是CN属性值,表示证书需要包含的域名,可以包含多个。
subjectPKInfo表示服务器密钥对的公钥,可以是RSA公钥或国密SM2公钥。
attributes表示可选信息,比如服务器主体的邮件地址等相关信息。
在证书中,服务器公钥、域名是服务器主体重要的内容。服务器主体使用该密钥对的私钥对certificationRequestInfo进行数字签名。
证书生成格式
ASN.1标准用于描述证书结构,而证书本质上是一个文件,需要一种专门的格式,才能在互联网中传输,证书需要通过一个规则将ASN.1转换为二进制文件。在X.509证书中,使用的编码方式是Distinguished Encoding Rules(DER),ASN.1和DER的关系类似于字符集和编码的关系。
DER是一个二进制文件,为了方便传输,可以将DER转换为PEM(Privacy-enhanced Electronic Mail)格式,PEM是Base64编码方式,以-----BEGINCERTIFICATE-----开头、-----END CERTIFICATE-----结尾。
还有一些其它不常用的格式:
BER。Basic Encoding Rules(BER)是DER的一个子集,
CER。Canonical Encoding Rules(CER)是另外一种编码标准,用来编码ASN.1结构。
PKCS#12格式。微软发布的一种格式,文件后缀一般是.pkcs12、.pfx、.p12。
PKCS#7格式。证书的另外一种格式,主要用来进行数字签名和数据加密,文件后缀一般是.p7b或者.p7c
证书生成过程
一般生成证书的流程为:
用户生成一对密钥对,比如SM2密钥对。
生成CSR文件,包含域名、公钥、签名等,发送给CA机构。
CA机构根据CSR文件生成证书,然后将证书下发给用户。
下面制作一张自签名证书为例,说明证书的制作过程。
生成SM2私钥
$ gmssl ecparam -genkey -name sm2p256v1 -text -out sm2_user.key
ecparam 表示采用椭圆曲线算法 -name sm2p256v1 指定椭圆曲线名称,这里指定了国密定义的椭圆曲线。
后SM2私钥保存到 sm2_user.key
ASN1 OID: sm2p256v1
NIST CURVE: SM2
-----BEGIN EC PARAMETERS-----
BggqgRzPVQGCLQ==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIONlieRy6aZ0q9o1z7LRii5HScKYIvLVcgaeM0x+FtyXoAoGCCqBHM9V
AYItoUQDQgAECvItoLwmG+Ws1GvLXsJbM+DgRbdY37MRloE6WDn6X/S3l5lKHIAQ
6ZH0QMSqQwg/LdvoI3s80/CMZJHnWqn6pA==
-----END EC PRIVATE KEY-----
注意:SM2私钥本质上是一串随机数,这里还包含了椭圆曲线的一些参数,并进行了PEM编码。
创建证书请求:
$ gmssl req -new -key sm2_user.key -out sm2_user.req
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [CN]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
这里会生成一个CSR,并保存到一个文件中。前面讲过,需要对CertificationRequestInfo进行数字签名,所以命令行需要传入SM2私钥。
可以看到,生成CSR时还要提供一些信息,比如国家、城市、公司名之类的信息,以后查看证书信息时,显示的就是这些信息。这里只是开发测试,所以填写什么内容无关紧要,直接使用默认值。
后生成的CSR文件如下:
-----BEGIN CERTIFICATE REQUEST-----
MIIBATCBpwIBADBFMQswCQYDVQQGEwJDTjETMBEGA1UECAwKU29tZS1TdGF0ZTEh
MB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYI
KoEcz1UBgi0DQgAECvItoLwmG+Ws1GvLXsJbM+DgRbdY37MRloE6WDn6X/S3l5lK
HIAQ6ZH0QMSqQwg/LdvoI3s80/CMZJHnWqn6pKAAMAoGCCqBHM9VAYN1A0kAMEYC
IQDlPL8JQRMBEM89hOMd2gOSG7bZZjI/bKnub1YO0wrEVAIhAOIR1GsrCG8e1MzU
NQpsv0wKypISh1wdmN86kHzQE/20
-----END CERTIFICATE REQUEST-----
生成证书:
$ gmssl x509 -req -days 365 -in sm2_user.req -signkey sm2_user.key -out sm2_user_cert.pem
Signature ok
subject=C = CN, ST = Some-State, O = Internet Widgits Pty Ltd
Getting Private key
参数中 -days 365 指的是证书的有效期为365天。生成的证书文件如下:
-----BEGIN CERTIFICATE-----
MIIBejCCASACCQDzHKj1UYRCVjAKBggqgRzPVQGDdTBFMQswCQYDVQQGEwJDTjET
MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ
dHkgTHRkMB4XDTIxMDMzMTA3Mjk0NloXDTIyMDMzMTA3Mjk0NlowRTELMAkGA1UE
BhMCQ04xEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdp
ZGdpdHMgUHR5IEx0ZDBZMBMGByqGSM49AgEGCCqBHM9VAYItA0IABAryLaC8Jhvl
rNRry17CWzPg4EW3WN+zEZaBOlg5+l/0t5eZShyAEOmR9EDEqkMIPy3b6CN7PNPw
jGSR51qp+qQwCgYIKoEcz1UBg3UDSAAwRQIhAJRL6l3CeSyoUrWbqFuGqKrIyIjr
5zbtoBM4/26jOPb+AiBohiMRwPnAqIkxG8PS3FFrtsZH11uBZ3vrq3ozhV2G7A==
-----END CERTIFICATE-----
因为进行了PEM编码,看不出里面的内容,我们可以借助工具查看证书内容。
$ gmssl x509 -text -in sm2_user_cert.pem -noout
Certificate:
Data:
Version: 1 (0x0)
Serial Number:
f3:1c:a8:f5:51:84:42:56
Signature Algorithm: sm2sign-with-sm3
Issuer: C = CN, ST = Some-State, O = Internet Widgits Pty Ltd
Validity
Not Before: Mar 31 07:29:46 2021 GMT
Not After : Mar 31 07:29:46 2022 GMT
Subject: C = CN, ST = Some-State, O = Internet Widgits Pty Ltd
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:0a:f2:2d:a0:bc:26:1b:e5:ac:d4:6b:cb:5e:c2:
5b:33:e0:e0:45:b7:58:df:b3:11:96:81:3a:58:39:
fa:5f:f4:b7:97:99:4a:1c:80:10:e9:91:f4:40:c4:
aa:43:08:3f:2d:db:e8:23:7b:3c:d3:f0:8c:64:91:
e7:5a:a9:fa:a4
ASN1 OID: sm2p256v1
NIST CURVE: SM2
Signature Algorithm: sm2sign-with-sm3
30:45:02:21:00:94:4b:ea:5d:c2:79:2c:a8:52:b5:9b:a8:5b:
86:a8:aa:c8:c8:88:eb:e7:36:ed:a0:13:38:ff:6e:a3:38:f6:
fe:02:20:68:86:23:11:c0:f9:c0:a8:89:31:1b:c3:d2:dc:51:
6b:b6:c6:47:d7:5b:81:67:7b:eb:ab:7a:33:85:5d:86:ec
可以对照着前面的证书结构,看看上面的证书内容。
发一个数字证书这么容易吗?对的,借助工具任何人都可以很容易颁发一个数字证书,至于这个证书别人是不是承认,这个就不是证书本身能解决的了。。。这就如同现实世界中,你也可以给自己颁发一个国外程序员大师,你也可以盖上自己的印,表明此证书确实是你颁发的。剩下的问题就是如何让这个证书有价值了。。。
要让用户信任颁发的数字证书,这里就需要引入 CA 可信了。
(文章转自云水木石,作者陈正勇,如有侵犯到您的权益,可以随时联系在线客服,我们时间删除。)