一 出现背景
加密通信(二):加密通信模型 所述的加密通信中还有两个问题:
- 如何确认公钥的安全性(确保你拿到的接收者的公钥是真正的接收者的、没有被篡改的)。如果每次通信开始时接收者将公钥发送给发送者,那么有可能会被第三方截取/替换,结合其他技术冒充接收者盗取信息。
- 如何存储大量公钥,并保证安全。如果发送者事先通过安全途径获取接收者公钥,就需要将其妥善存储。如果发送者要给成千上万的接受者发送信息,那它就要保存成千上万个公钥,还要及时共享公钥并保证安全。
CA证书的作用就是为了解决以上两个问题,每个接收者的公钥是否可信由CA证书来验证。
二 CA证书生成
CA颁发机构:用来颁发CA证书的机构或公司,他们是无条件可信的。
CA证书的生成过程如下:
- 申请者生成自己的公钥S/私钥S,并将公钥S、自己的身份信息(域名、国家等)一并发给CA颁发机构
- CA颁发机构汇总申请者信息,额外再加上自己的信息(颁发者信息)生成CA证书的明文部分
- CA颁发机构对明文部分计算生成hash值,然后使用自己的私钥R对hash值加密生成指纹(即数字签名),和明文信息一起生成最终的CA证书
- 将生成的CA证书发回给申请者,完成。
三 CA证书的使用
简述CA证书的工作模型(网站访问为例):
- 此处默认客户C已经拿到了CA颁发机构的公钥R(这一步本质是通过CA根证书做到的)
- 客户C访问网站S,网站S将自己的CA证书发给客户C
- 客户C使用CA机构的公钥R验证CA证书的合法性(使用公钥R解密CA证书中的指纹信息得到hash值a,对明文信息计算hash值b,比较两个hash值是否相等)
- 如果验证合法则读取CA证书中网站S的公钥S
- 使用公钥S进一步进行加密通信。。。。
从以上过程可以看出,我们通过CA机构的公钥R验证了网站的公钥S的正确性,同理我们可以通过公钥R验证其他更多的网站公钥的正确性,这样我们只要保存少量CA机构的公钥既可以访问大量的网站了。
这里还有一个问题,如何保证我们拿到的CA机构的公钥是正确的??答案是根证书。
四 CA根证书
上面第1步中,默认已经获取了CA颁发机构的公钥R。其本质是通过根证书获取。
根证书有个特点它的颁发者和使用者是相同的,都是CA证书颁发机构,根证书中记录的公钥信息就是CA机构的公钥R。
CA机构是可信机构,因此操作系统(如windows、linux)会将世界上可信CA机构的根证书默认集成在操作系统中。换句话说操作系统提供商会替用户验证根证书的可信度,点对点的操作避免了中间人攻击导致不可信根证书植入到我们系统中。另外,用户也可以自己安装根证书到操作系统中(自己确认根证书的可信度)。因此根证书是已经内置在操作系统的,不需要额外获取。
再述CA证书的工作模型(网站访问为例):
- 客户C访问网站S,网站S将自己的CA证书发给客户C
- 客户C读取证书明文中颁发者信息,根据颁发者在操作系统查找根证书
- 若找到根证书则获取根证书公钥R,使用公钥R验证网站S的证书,如果验证成功则使用证书中的公钥S与网站做进一步通信,验证失败则结束通信
- 若找不到根证书,则结束通信
五 CA中间证书
在CA证书实际应用的过程中,所有的使用者证书并不都是直接通过根证书验证的,其中还有一些中间证书,实际的证书颁发结构应该是树状结构:
中间证书的存在有很多种情况,如果所有的证书都从根证书颁发,如果根证书作废则影响范围很大,使用中间证书可以还可以实现分类管理,比如按有效期分类。
证书的树形结构就形成了证书链,证书的验证就需要逐级验证,以CA证书2为例:
- 根证书验证中间证书A
- 中间证书A验证中间证书C
- 中间证书C验证CA证书2
中间有一个环境验证不过,则无法完成验证
中间证书如何存储:
比如在https/tls协议通信过程中,如果服务器的CA证书使用了中间证书,那么获取中间证书一般有两种方式:
- 根据服务器证书中的信息自动下载中间证书,windows、linux支持这种方式,但android移动设备不支持,而且某些中间证书可能会因为墙的原因无法顺利下载。
- 服务器端存储中间证书,在tls握手阶段将CA证书和中间证书一并发给客户端浏览器,浏览器逐级验证证书。
目前第二种方式是普遍适用的方式。