引言
我们知道,http协议属于明文传输协议,交互过程以及数据传输都没有进行加密,通信双方也没有进行任何认证,通信过程非常容易遭遇劫持、监听、篡改,比如我们打开一些http网站时会跳出一些不属于网站本身的弹出广告,这种情况下就是遭遇运营商的流量劫持。严重情况下,会造成恶意的流量劫持等问题,甚至造成个人隐私泄露(比如银行卡卡号和密码泄露)等严重的安全问题。
可以把http通信比喻成寄送信件一样,A给B寄信,信件在寄送过程中,会经过很多的邮递员之手,他们可以拆开信读取里面的内容(因为http是明文传输的)。A的信件里面的任何内容(包括各类账号和密码)都会被轻易窃取。除此之外,邮递员们还可以伪造或者修改信件的内容,导致B接收到的信件内容是假的。
比如常见的,在http通信过程中,“中间人”将广告链接嵌入到服务器发给用户的http报文里,导致用户界面出现很多不良链接; 或者是修改用户的请求头URL,导致用户的请求被劫持到另外一个网站,用户的请求永远到不了真正的服务器。这些都会导致用户得不到正确的服务,甚至是损失惨重。
考虑到http的这些隐患,目前像Google、Apple都在大力呼吁开发者使用全站https连接.
1.https工作原理
为了阐述清楚https的工作原理,对下面几种情况进行分析。
1.1 只采用对称加密
理论上,如果Server给Client的消息是密文的,只有服务器和客户端才能读懂,就可以保证数据的保密性。同时,在交换数据之前,验证一下对方的合法身份,就可以保证通信双方的安全。
那么,问题来了,服务器把数据加密后,客户端如何读懂这些数据呢?这时服务器必须要把加密的密钥(对称密钥,后面会详细说明)告诉客户端,客户端才能利用对称密钥解开密文的内容。
但问题是,如果Server将这个对称密钥以明文的方式发给Client,还是会被中间人截获,中间人也会知道对称密钥,依然无法保证通信的保密性。
到这里可以发现,只采用对称加密的方法不可行。
1.2 对称加密+非对称加密
在1.1的基础上,我们引入非对称加密。在非对称加密算法里,公钥加密的数据,有且只有唯一的私钥才能够解密,所以服务器只要把公钥发给客户端,客户端就可以用这个公钥来加密进行数据传输的对称密钥。
此时,客户端利用公钥将对称密钥发给服务器时,即使中间人截取了信息,也无法解密,因为私钥只部署在服务器,其他任何人都没有私钥,因此,只有服务器才能够解密。
服务器在拿到客户端的信息并用私钥解密之后,就可以拿到对称密钥,通过这个对称密钥来进行后续通信的数据加解密。
除此之外,非对称加密可以很好的管理对称密钥,保证每次数据加密的对称密钥都是不同的,这样的话,即使客户端病毒获取到通信缓存信息,也无法窃取正常通信内容。
上述过程的示意图如下:
事实上,我们离正确答案已经非常近了。但是,wait a moment,让我们考虑一下这种情况:如果在三次握手或者客户端发起http请求过程中,客户端的请求被中间人劫持,那么中间人就可以伪装成假冒客户端和Server通信,同时,中间人又可以伪装成“假冒服务器”和客户端通信。接下来,我们详细阐述中间人获取对称密钥的过程:
- step1:中间人在收到Server发给Client的公钥后,并没有发给客户端,而是将它保存起来,同时将中间人自己的公钥发给Client;
- step2:Client使用中间人的公钥将对称密钥加密后发送出去;
- step3:中间人截获到这个信息,由于是使用中间人的公钥加密的,因而使用它的私钥可以解密获取到对称密钥并保存;之后,中间人使用之前保存的Server的公钥将对称密钥加密发回给Server;
- step4:此时,客户端、中间人、服务器都拥有了一样的对称密钥,后续客户端和服务器的所有加密数据,中间人都可以通过对称密钥解密出来。
上述过程的示意图如下:
此时,在Client和Server看来,它们的通信过程和前面的是一样的,但其实所有数据都已经被中间人窃取了。
1.3 数字证书
为了解决1.2的问题,我们引入了数字证书的概念。
服务器首先生成公私钥,然后将公钥提供给相关机构(CA),CA将公钥放入数字证书并将数字证书颁布给服务器(其实主要就是利用CA的私钥给Server的公钥打上标签,由于私钥无法伪造,从而可保证唯一性).
此时Server就不是简单的把公钥发给Client,而是给Client一个数字证书,这个证书里面加入了一些数字签名的机制,保证了数字证书一定是Server发给Client的。此时,即使中间人想发送一个伪造的证书,但是由于CA不会给它颁发这个证书(因为它没有经营这个网站的资质嘛,所以CA的信誉、对申请者的审核、对自己私钥的保管这3点非常重要,任何一环出问题,都会导致中间人有机可乘,从而重蹈1.2的覆辙),从而无能为力。或者中间人发送自己网站的数字证书,那么必然会不能通过校验,从而导致会话中断。
加入了CA数字签名认证的SSL会话过程如下:
显然,由于数字证书的引入,保证了整个通信过程不被中间人窃取。
2.https完整过程
上面详细阐述了https可靠的原理,下面详细分析一下浏览器与Server建立https连接的过程。
TLS/SSL协议不仅仅是一套加密传输的协议,更是一件经过艺术家精心设计的艺术品,TLS/SSL中使用了非对称加密,对称加密以及HASH算法。握手过程如下:
- step1:浏览器将自己支持的一套加密规则发送给Server;
- step2:Server从中选择一组加密算法与Hash算法,并将自己的身份信息以数字证书的形式会给浏览器;证书里面包含了网站地址,加密公钥以及证书的颁发机构等信息;
- step3:浏览器获得网站证书之后要做以下工作:
- 验证证书的合法性(颁发证书的机构是否合法,证书中包含的网站地址是否与正在访问的地址一致等),如果证书受信任,则浏览器栏里面会显示一个小锁头,否则会给出证书不受信的提示;
- 如果证书受信任,或者用户接受了不受信的证书,则浏览器会生成一串随机数的密码,并用证书中的公钥加密;
- 使用约定好的HASH算法计算握手消息,并使用生成的随机数对消息进行加密,最后将之前生成的所有信息发送给网站
- step4:网站接收浏览器发来的数据之后要做以下事情:
- 使用自己的私钥将信息解密取出密码,使用密码解密浏览器发来的握手信息,并验证Hash是否与浏览器发来的一致
- 使用密码加密一段握手信息,发给浏览器
- step5:浏览器解密并计算握手信息的Hash,如果与Server发来的Hash一致,此时握手过程结束,之后所有的通信数据将由之前浏览器生成的随机密码并利用对称加密算法进行加密。
上述过程的时序图如下: