目录
前言
一、应用场景
二、公钥和私钥的加密体系
三、如何安全地分发公钥给公众
四、CA证书(也就是中间根证书)
总结
前言
一、应用场景
在开始了解非对称加密以及公钥和私钥之前,我们先来了解一下它们的应用场景:
1、一个在网络上公开的服务器要对外提供服务,它需要一种安全通信手段;
2、服务器需要一个较为简单的管理用户密钥的手段,而不是为每一个用户创建一个密钥,否则那么多用户,那么多密钥,不论是管理,还是安全性,都难以保证;
2、这个服务器需要对公众证明它是一台合法的服务器,而不是什么钓鱼服务器,在https普及之前,钓鱼服务器是很普遍的。
二、公钥和私钥的加密体系
公钥和私钥是成对的,它们互相解密。也就是说用公钥加密的信息,只能用它对应的 私钥解密,哪怕是用公钥都解不开。
反之亦然。
假设服务器 S首先通过非对称加密算法为自己计算出来一对密钥,也就是私钥 + 公钥,
S的私钥需要S自己严格保密,不能透露给第三方。
S的公钥则是S发布给公众,用于公众与S之间进行安全通信。这样服务器只需要保管好自己的私钥不被泄露,并保证能安全的分发自己的公钥即可对用户提供安全的网络服务。
假设B是公众用户之中的一员,S与B之前的通信:
B 使用S的公钥加密信息,使用网络发送 ---------发送-------> S收到后,使用S的私钥解密信息;
理想的情况下,S发送信息给B也应该按照如下流程:
S使用S的私钥加密信息,使用网络发送 ---------发送-------> B收到后,使用S的公钥解密报文;
但是S作为服务器,需要为很多用户同时提供服务,并且往往提供的服务可能会发送很大的信息(或文档)给用户B,而非对称加密算法是比较慢的,所以我们的通信需要作出一些改变:
S 使用Hash算法计算出“发送信息”的“摘要” -------S使用S的私钥加密这段“摘要” 生成“数字签名”-------- S将“数字签名” 与 “发送信息”一起作为一个信件使用网络发送
---------发送-------> B收到后,使用S的公钥解密信件中的“数字签名” ----得到“摘要” ,证明信件确实来自S(如果能解开,说明确实是来自S) ----- 然后再对信件中的“发送信息” 本身使用Hash函数得到一个“摘要验证副本”,将得到的“摘要验证副本” 与 “摘要”比对,如果一致,证明信件没有被纂改;
PS:为什么不直接加密信息本身而只是加密信息的摘要?非对称加解密算法比较慢,如果信息是一个大文档,则更是难以操作,所以只加密信息的摘要而不是整个信息本身。如果用户自己想检测签名是否有效,可以解密签名得到信息提供方的“摘要”,并自己对信息进行哈希转换生成“验证摘要”,看看这两个摘要是否匹配,如果匹配,则证明信息在传输中没有被纂改,这就是有效签名;如果不匹配,说明信息在传输中被纂改了,这叫做无效签名。这个过程其实就是验证签名,后面我们会用到这个知识。
我们看到上述的通信方法提供了信息交换的安全保证,但是其通信流程也相当繁琐,正是由于非对称加密算法的相比较对称加密算法复杂效率较低,我们在实际的应用中,会使用非对称加密+对称加密两者结合的方式来进行数据的安全通信。
也就是说先使用上述的方法进行非对称加密中的公钥分发,当非对称加密的公钥分发完成之后,就可以利用非对层加密来交换对称加密的密钥,再之后的通信过程,将只需要使用对称加密的方式通信。这样既兼顾了安全性,又提高了通信的性能。
经过多年发展,诞生了SSL/TLS技术,到今天TLS技术经过了数次迭代,具体的我们可以继续学习TLS协议,来了解TLS是如何对上述的通信流程作出改进的。
三、如何安全地分发公钥给公众
在第二节中,我们讲到了一种利用非对称加密来传递一个带有数字签名的信息给用户的通信方法,在TLS的体系中,这种方法就用在公钥的信息交换过程中(也就是公钥的安全分发),
但是上述方法存在一个很明显的漏洞,那就是S的公钥自身的合法性没有验证,换句话说就是B无法知道S的公钥真的是S的公钥,并且早期的公钥是明文在网络上传递给用户。
于是就可能出现这样的情况:在上面的例子中,我们引入一个攻击者spy,spy想欺骗B,spy偷偷使用了B的电脑(或者使用其它手段侵入了B的电脑 ),用spy的公钥替换了S的公钥;又或者在网络中间拦截S与B之间的通信并发送了假的公钥给B。
此时,B实际拥有的是spy的公钥,但是B此刻还不知情,还以为这是S的公钥。因此,spy就可以冒充S,用spy的私钥做成"数字签名",写信给B,让B用spy的公钥进行解密。
简单点说,就是spy通过发布了假冒的S的公钥(其实是spy自己的公钥),从而实现了对S的冒充。
为了防止spy冒充S的这种情况,我们需要引入一个可信的第三方C来证明S就是S,而不是其它人:
这里的引入的C,我们一般称作"证书中心"(certificate authority,简称CA),为公钥做认证。证书中心C用自己的私钥,对S的公钥和一些相关信息(包含了S的个人信息/域名等)一起加密,生成"数字证书"(Digital Certificate)S.cert--姑且以此名字命名,并且数字证书中还包含了CA机构信息。
服务器S拿到C为S颁发的"数字证书" S.cert之后,就可以在TLS握手协议中分发S的证书 S.cert(内含S的公钥)了,并进一步改进上面的通信流程:
S使用Hash算法计算出“待发送的证书S.cert”的“摘要” -------S使用S的私钥加密这段“摘要” 生成“数字签名”-------- S将“数字签名” 与 “待发送的证书S.cert”一起作为一个信件,使用网络发送
---------发送-------> B收到后,首先读取证书S.cert中的CA机构信息,查找本地是否有该机构的CA证书,然后使用该CA机构的证书中的公钥,也就是C的公钥,解密信件中的"数字证书","数字签名",并验证签名(前面已经讲过怎么验证签名);如果发现该机构的CA证书无效或者不可信,或者验证出发现是无效签名,证明这个证书不是S的,那么B可以立即停止通信(这是因为"数字证书"是由CA机构审核后发布给S、spy的,信息的真实性由CA机构作出了保证,这样spy想通过将spy自己的"数字证书"替换S的"数字证书"来冒充S,就不再可行了)----
上面这个流程在TLS协议中,是一个很重要的步骤,那就是下图中的第3步骤,服务器S发送它自己的证书给用户B,用户B对该证书进行证书验证,当然实际应用中,比这个要复杂,同时还存在一个证书链的验证问题。
同样的,如果通信的Server还要求Client也进行证书验证,也就是双向证书验证(多用于银行金融系统),那就是下面图中的第4步。
TLS握手协议
大家也看到了这里CA机构需要为证书提供真实性的保证,并且B也有CA机构的公钥。所以一个可信的正规的CA机构就很重要了。
四、CA证书
这里有个问题,证书的真实性由CA机构来保证,那么CA机构自己的证书,又由谁来保证呢?
我们来看一段百度百科的讲解:
在密码学和计算机安全领域中,根证书是未被签名的公钥证书或自签名的证书。
从技术上讲,证书其实包含三部分,用户的信息,用户的公钥,还有CA中心对该证书里面的信息的签名。验证一份证书的真伪(即验证CA中心对该证书信息的签名是否有效),需要用CA 中心的公钥验证,而CA中心的公钥存在于CA中心自己的证书内,故用户需要下载该证书,但使用该CA证书验证又需先验证该CA证书本身的真伪,故又要用签发该CA证书的更上一级CA证书来验证,这样一来就构成一条证书链的关系,这条证书链在哪里终结呢?答案就是根证书,根证书是一份特殊的证书,它的签发者是它本身,下载根证书就表明您对该根证书以下所签发的证书都表示信任,而技术上则是建立起一个验证证书信息的链条,证书的验证追溯至根证书即为结束。所以说用户在使用自己的数字证书之前必须先下载根证书。
其实这就引入了一个证书链的概念,操作系统一般会内置了一批可信的正规的CA机构的证书,用户在验证某一个证书的过程,其实就是在向根证书追溯的过程,验证证书----验证中间根证书 1...-验证中间根证书2...----验证根证书,其实这个过程并不一定要追溯到顶级根证书,只要用户在向顶级根证书追溯的过程中,发现了一个可信的根证书,整个验证过程就通过了。
如果一直找不到一个用户可信的根证书(这种情况是存在的,例如用户自己取消了对某一些CA机构的信任而该证书又恰恰是由这个用户不信任的CA机构签发的),那么验证最终会失败。
只要用户自己不胡乱添加证书,一般是可以保证安全的,而这些可信的正规的CA机构的证书最后追根溯源,都是由某一个国家的法律在背后支撑。
总结
公钥:非对称加密产生,用于服务方发布给公众使用
私钥:非对称加密产生,用于服务方自己解密公众发来的用公钥加密的信息、或用于生成数字签名;CA机构使用自己的私钥加密证书申请者(服务方)的个人信息、公钥生成证书并颁发给申请者(服务方);
摘要:服务方将要发送的信息进行哈希运算,得到一个信息的摘要;
数字签名:服务方对自己发送给公众用户使用的信息的 摘要 使用服务方自己私钥进行加密,得到数字签名;
数字证书:由CA机构颁发给服务方,内部包含了服务方的个人信息,如公司名、域名地址等,还包含了服务方的公钥,CA机构使用了CA机构自己的私钥将这些信息加密打包生成数字证书,并颁发给服务方;
TLS加密认证,就是建立在用户首先信任CA机构的前提下,用户自己已经下载好了该CA机构的证书(内含CA机构的公钥),然后用户在与服务方通信的时候,通过验证服务方发过来的 服务方的证书(通过CA机构的证书--CA的公钥--来解密,然后验证)。只有通过验证的服务方,才能继续与该用户通信。