0x00 前言
数字证书是公钥密码学的典型应用,是信息安全的基础,今日好好复习一下
0x01 简单应用原理
最重要的一点,数字证书是保障公钥的可靠性
以下流程参考阮一峰老师的经典流程:
假设A给B写一份信。
那么这封将包含如下三部分内容:
1.信本身的内容(直接可以看到,未加密)
2.A的数字签名 (是由信本身的内容经过hash算法计算得到digest摘要,然后用 A的私钥 加密而来的)
3.A的数字证书 (是A 向数字证书中心(CA)申请的,是由 A的个人信息,A的公钥 等经过CA的私钥 加密而来的)
然后B先用CA提供的公钥解开数字证书,根据得到的内容,如A的个人信息,确定是A发过来的,然后拿到了A的公钥。
接着,用A的公钥解开A的数字签名 就能得到信本身内容的摘要。然后将信的第一部分,即信的本身内容 经hash计算得到一个新的摘要,将两个摘要比较,如果相同 说明信的内容没有被篡改。
这里B要做的就是查询CA是否可信,然后用可信CA的公钥解开A的数字证书,得到A的个人信息和公钥,然后利用A的可信公钥验证A的数字签名,可见,数字证书的最大作用就是保证A的公钥的真实性,抗抵赖
0x02 Https的应用
https传输,访问google网站:
握手时用非对称加密传输对称加密的密码,数据传输时用对称加密的密码加密数据(对称加密解密速度比非对称加密快)
过程:
- 浏览器发送自己支持的加密规则给google
- google选择一组加密算法和HASH算法,并将自己的数字证书发给浏览器
- 浏览器验证数字证书的合法性(验证证书的数字签名),然后生成一个随机数,从google的数字证书里面获取google的公钥,用这个公钥加密随机数。用约定的hash算法生成握手消息的摘要,并用生成的随机数加密摘要。把握手消息、加密的摘要、加密的随机数发给google
- google用自己的私钥解密随机数,然后用随机数解密摘要,再用hash生成收到的握手消息的摘要与解密的摘要对比,验证正确性。
- google一样用hash算法生成握手消息的摘要,并用解密的随机数加密摘要。然后把握手消息、加密的摘要发给浏览器
- 浏览器验证摘要成功后,握手完成。之后通信的数据用之前浏览器生成的随机密码加密后传输。
0x03 问题的根源:(证书中的公钥的真实性和完整性)
由上面的例子中我们看到,https传输的过程中,Google会发来自己的证书,里面包含了Google的公钥,用户浏览器要使用这个公钥加密消息再发送到Google服务器进行协商,其中,这个公钥的完整性和真实性就是关键,如何保证这个证书里面的公钥真的是Google的呢?这就是为什么要验证证书的数字签名的理由,那么如何验证呢?就是通过CA了,CA会通过自己的私钥对可信的包含正确公钥的Google证书进行数字签名,用户浏览器要使用CA的公钥验证证书的数字签名。
0x04 证书链
根据上面的说明,证书的出现是为了保证双方的公钥是合法的,没有被篡改的,那么谁保证证书的合法性和完整呢?那就是CA,但是直接从知名的CA获得签名证书是昂贵的,所以,就出现了由知名CA签发了一个证书A,再又证书A签发证书B的方式,这就是证书链。
本质来说,就是顶级CA认证了A的公钥,然后A的公钥再认证B的公钥。
证书链的构成:
end-user :baidu.com 包含用来加密传输数据的公钥的证书,是HTTPS中使用的证书
intermediates CA :CA用来认证公钥持有者身份的证书,即确认HTTPS使用的end-user证书是属于baidu.com的证书。这类intermediates证书甚至可以有很多级。
root CA :用来认证intermediates证书是合法证书的证书。
简单来说,end-user证书上面几级证书都是为了保证end-user证书未被篡改,保证是CA签发的合法证书,进而保证end-user证书中的公钥未被篡改
如何验证证书链
链式向上验证证书,直到Root Certificates,先验证用intermediates CA 签发的end-user的证书的数字签名,再利用root CA验证intermediates CA的数字签名。下图就是访问百度获得的三张证书
下面的图片很好的表达了如何进行证书链的认证:
从哪获取非根证书的颁发者证书?
网站的证书里是包含上级颁发机构的证书获取地址的
总体来说浏览器对证书的验证包括下面几项:
验证证书是否在有效期内
验证证书是否在有效期内
验证吊销有CRL和OCSP两种方法
- 验证证书是否是上级CA签发的(上面讨论的重点)
x.509 证书编码格式
我们平时会见到一大堆后缀名不同的证书,但先抛开后缀名字不谈,x.509就只有两种常用的编码格式
PEM - Privacy Enhanced Mail,打开看文本格式,以”—–BEGIN…”开头, “—–END…”结尾,内容是BASE64编码.
查看PEM格式证书的信息:openssl x509 -in certificate.pem -text -noout
Apache和*NIX服务器偏向于使用这种编码格式.DER - Distinguished Encoding Rules,打开看是二进制格式,不可读.
查看DER格式证书的信息:openssl x509 -in certificate.der -inform der -text -noout
Java和Windows服务器偏向于使用这种编码格式.
相关的文件扩展名,引用一下别人的
这是比较误导人的地方,虽然我们已经知道有PEM和DER这两种编码格式,但文件扩展名并不一定就叫”PEM”或者”DER”,常见的扩展名除了PEM和DER还有以下这些,它们除了编码格式可能不同之外,内容也有差别,但大多数都能相互转换编码格式.
CRT - CRT应该是certificate的三个字母,其实还是证书的意思,常见于*NIX系统,有可能是PEM编码,也有可能是DER编码,大多数应该是PEM编码,
CER - 还是certificate,还是证书,常见于Windows系统,同样的,可能是PEM编码,也可能是DER编码,大多数应该是DER编码.
PFX/P12 - predecessor of PKCS#12,对*nix服务器来说,一般CRT和KEY是分开存放在不同文件中的,但Windows的IIS则将它们存在一个PFX文件中,(因此这个文件包含了证书及私钥)这样会不会不安全?应该不会,PFX通常会有一个”提取密码”,你想把里面的东西读取出来的话,它就要求你提供提取密码,PFX使用的时DER编码,如何把PFX转换为PEM编码?
openssl pkcs12 -in for-iis.pfx -out for-iis.pem -nodes
这个时候会提示你输入提取代码. for-iis.pem就是可读的文本.
生成pfx的命令类似这样:openssl pkcs12 -export -in certificate.crt -inkey privateKey.key -out certificate.pfx -certfile CACert.crt
其中CACert.crt是CA(权威证书颁发机构)的根证书,有的话也通过-certfile参数一起带进去.这么看来,PFX其实是个证书密钥库.
参考:
http://www.ruanyifeng.com/blog/2011/08/what_is_a_digital_signature.html
https://www.jianshu.com/p/46e48bc517d0