但是这时还有一个漏洞,问题出在数字签名过程中私钥加密以及后面公钥解密的不安全性。图中李四在拿公钥A解密的时候,这个公钥A真的是张三的公钥吗?也许张三传输公钥给李四的过程中被王五截断,王五声称自己是张三,并把自己的公钥给了李四,然后王五用自己的私钥对木马程序进行签名,进行对称加密后再使用李四的公钥加密,最后传输给李四,这样一来李四以为王五就是张三,导致的结果是李四对木马程序完全信任。
如何解决这个漏洞呢?只要保证李四获得的公钥A真的是来源于张三即可,如何保证呢?互联网之下,数据传输的两端可能谁都不认识谁,谁也不相信谁,所以最终还是依靠公益性的第三方组织——CA。
1.5 CA、PKI及信任CACA(Certificate Authority)是数字证书认证中心,常称为证书颁发机构,申请者提交自己的公钥和一些个人信息(如申请者国家,姓名,单位等)给CA,CA对申请者的这些信息单向加密生成摘要信息,然后使用自己的私钥加密整个摘要信息,这样就得到了CA对申请者的数字签名,在数字签名上再加上CA自己的一些信息(如CA的机构名称,CA层次路径等)以及该证书的信息(如证书有效期限),就得到了所谓的数字证书。
过程如下图。
如果某用户信任了该CA,就获取了该CA的公钥(实际上信任CA的其中一个作用就是获取CA公钥),使用该公钥解密数字证书就可以验证申请者的信息以及申请者公钥的可靠性(申请者的公钥只被CA的私钥加密,解密该私钥后只是需要验证可靠性)。
这里的关键是CA使用自己的私钥给申请者加密,那么如何保证CA是可信并且合法的呢?根CA是通过自签署数字证书的方式标榜自己的可信性和合法性,第一级子CA由根CA颁发合法数字证书,第二级直至所有的子CA都由上一级子CA颁发数字证书。对于多级子CA只需要信任根CA即可,因为获取了根CA的公钥,可以解密第一级子CA的证书并获取验证第一级子CA的公钥,层层递进,最终获取到为申请者颁发数字证书的机构并获取它的公钥。
正是这些根CA和子CA组成了PKI。
信任CA后,每次接收到需要解密的数字证书时,还要去该颁发机构指定网站的证书吊销列表(CRL)中查询该证书是否被吊销,对于吊销后的证书应该不予以信任,这是信任CA的第二个作用。导致证书被吊销的可能性不少,例如申请者的私钥被黑客获取,申请者申请吊销等。
也有公司使用自签的证书,例如某些银行、12306有时候就要求下载证书并安装。使用自签证书的好处当然是省钱、方便啦。
1.6 数字证书类型和内容PKI的两种实现方式TLS和SSL使用的证书格式都是x509,TLSv1和SSLv3基本等价,只不过SSL实现在OSI 4层模型中的应用层和传输层的中间,TLS实现在传输层。
还有PKI的另一种实现方式GPG,它的证书使用的不是x509格式。
数字证书中包含的信息有:申请者的公钥,证书有效期,证书合法拥有人,证书如何被使用,CA的信息,CA对申请者信息的数字签名。
1.7 SSL握手机制有了CA颁发的数字证书后,通信机制就和下图的机制完全不同了。
上图中每一段数据都签名加密,有了数字证书后实际上已经验证了身份,不需要每一段数据都签名,这能提升效率。在上图中的漏洞是无法确认获取的公钥A是否可信,有了数字证书后已经能够确认公钥A是可信的。但问题是公钥A本来目的是用来解密数字签名的,有了数字证书后不需要数字签名了,那公钥A不是多余的吗,如果多余,那把公钥A交给CA是不是也是多余的呢?
不多余,因为SSL的握手机制和数字签名机制完全不同。以下是单向验证机制,只验证服务端。
第一步:Visitor给出协议版本号、一个客户端随机数(Client random),以及客户端支持的加密方法。
第二步:Server确认双方使用的加密方法,以及一个服务器生成的随机数(Server random)。
第三步:Server发送数字证书给Visitor。