下面这个图为http和https的关系。HTTPS协议也是一个应用层协议,是在HTTP协议的基础上引入了一个加密层。我们在学习http协议时,也分析了http协议中传输数据都是明文传输,所以是不安全的,所以才会有了https协议,https协议会将http协议发送到网络中的数据先进行加密,然后再收到数据时再进行解密,这样在网络中传输的数据就是经过加密后形成的密文,这些数据就不是以明文的方式传输了。
要了解HTTPS协议,我们就需要先了解加密和解密。
加密就是把明文(要传输的信息)进行一系列变换,生成密文。
解密就是把密文再进行一系列变化,还原成明文。
在这个加密和解密的过程中,往往需要一个或者多个中间的数据,辅助进行这个过程,这样的数据成为密钥。
我们加密数据是为了让数据更加安全,不想要被除了通信两方的其它人知道这个数据的内容。下面我们通过一个"运营商劫持"的案例来说明为什么数据要进行加密。下面的过程为用户想要下载一个网易云音乐,但是用户通过浏览器发送的请求报文和接收网易云发送的响应报文都需要经过运营商设备,因为需要靠运营商设备来进行传输数据,那么如果是http协议传输数据,运营商设备中就可以查看到浏览器和网易云服务器之间的通信数据,那么运营商设备也可以修改两者之间的通信数据。例如运营商设备将网易云服务器发送给浏览器的响应报文中的网易云音乐的下载链接换为qq音乐的下载链接,那么这样就相当于qq音乐拦截了网易云音乐的一个用户。并且在现实中,不可能只是修改一个下载链接那么简单,即如果使用http协议的话,经过运营商的数据都可以被运营商拿到,这肯定是不安全的。所以传输的数据需要进行加密。
因为http的内存是明文传输的,明文数据会经过路由器、wifi热点、通信服务运营商、代理服务器等多个物理结点,如果信息在传输过程中被劫持,传输的内容就完全暴露了。劫持者还可以篡改传输的信息且不被双方察觉,这就是中间人攻击,所以我们才需要对信息进行加密。并且不止运营商可以劫持信息,其他的黑客也可以用类似的手段来劫持信息,以此来窃取用户隐私信息,或者篡改内容。
采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密,特征:加密和解密所用的密钥是相同的
常见对称加密算法:DES、3DES、AES、TDEA、Blowfish、RC2等。
特点:算法公开、计算量小、加密速度快、加密效率高。
对称加密其实就是通过同一个"密钥",把明文加密成密文,并且也能把密文解密成明文。
例如下面的一个简单的对称加密,按位异或。
非对称加密需要两个密钥来进行加密和解密,这两个密钥分别是公开密钥(public key,简称公钥)和私有密钥(private key,简称私钥)。
常见的非对称加密算法:RSA,DSA,ECDSA。
特点:算法强度复杂、安全性依赖于算法与密钥但是由于其算法复杂,而使得加密和解密速度没有对称加密解密的速度快。
非对称加密要用到两个密钥,一个叫做"公钥",一个叫做"私钥"。公钥和私钥是配对的,非对称加密最大的缺点就是运算速度非常慢,比对称加密要慢很多。
我们可以通过公钥对明文加密变为密文,然后通过私钥对密文解密变成明文。当然我们也可以反着用,即通过私钥对明文加密变成密文,然后通过公钥对密文解密变为明文。即当使用了其中一个密钥进行加密,那么就只能通过另一个密钥才能进行解密。
下面我们通过一个例子来体会非对称加密中的公钥和私钥。例如A要给B一些重要的文件,但是B可能不在.于是A和B提前做出约定:B说:我桌子上有个盒子,然后我给你一把锁,你把文件放盒子里用锁锁上,然后我回头拿着钥匙来开锁取文件.在这个场景中,这把锁就相当于公钥,钥匙就是私钥.公钥给谁都行(不怕泄露),但是私钥只有B自己持有.持有私钥的人才能解密拿到文件。
数字指纹(数据摘要),其基本原理是利用单向散列函数(Hash函数)对信息进行运算,生成一串固定长度的数字摘要。数字指纹并不是一种加密机制,但可以用来判断数据有没有被窜改。
摘要常见算法:有MD5、SHA1、SHA256、SHA512等,算法把无限的数据组合映射成有限的数字摘要,因此可能会有碰撞(两个不同的信息,算出的摘要相同,但是概率非常低)
摘要特征:和加密算法的区别是,摘要严格意义不是加密,因为没有解密,只不过从摘要很难反推原信息,通常用来进行数据对比。
下面我们举一个摘要的例子,例如当我们向网盘中上传文件时,网盘软件会先使用hash函数在你的本地算出这个文件的摘要,然后先上传摘要,如果网盘中查询到这个文件的摘要,那么就说明这个网盘中已经有这个资源了,所以网盘就不会再存储这个文件了,而是直接将网盘中这个文件资源的路径与当前用户建立映射。然后告诉用户文件上传完毕。如果用户上传的这个文件没有在网盘中,那么网盘会存储这个文件和这个文件的摘要。
再例如一个数据摘要应用的案例。
在公司的数据库中,保存用户的密码是不会使用明文来保存的,因为安全性太低,如果数据库被攻破,那么用户密码直接暴露。所以数据库中保存的都是用户密码经过hash函数得到的摘要,然后当用户登录时,如果要去数据库中进行账号密码验证,就会先将密码再经过hash函数得到摘要,然后拿账号和密码摘要去数据库中进行验证。这样公司的员工看到的数据库中的用户的密码也不是真正的密码,而是密码形成的摘要,这样员工就不能泄漏用户的信息了,而且数据库就算被攻破,数据库中存储的用户的密码也不是明文的,而是密码形成的摘要,并且因为摘要很难反推原信息,所以这样就算其它人得到了用户的密码摘要也没有用。
既然要保证数据安全,就需要进行加密,那么网络传输中就不再直接传输明文了,而是加密后形成的密文。前面我们说了加密的方式整体可以分为两大类:对称加密和非对称加密。下面我们来分析要得到一个安全的网络传输,应该怎样进行加密。
如果通信双方各自持有同一个密钥X,且没有其它人知道,这两方的通信安全当然是可以被保证的(除非密钥被破解)。
引入对称加密后,即使数据被黑客截获,但是由于黑客不知道通信双方的密钥是什么,因此就无法进行解密,也就不知道截获的数据的真实内容是什么了。但是我们知道一个服务器是会为很多客户端提供服务的,那么这么多客户端每个人用的密钥都必须是不同的(如果相同的话,那么服务器也会为黑客提供服务,黑客也就获取了这个所有用户的密钥)。因此服务器就需要维护每个客户端和每个密钥之间的关联关系,这就给服务器增加了开销。
还有一个最麻烦的事就是客户端和服务器是没有事先约定密钥X的,那么客户端将密钥X传给服务器就成为了一个问题,如果直接把密钥使用明文传输,那么黑客就能获得密钥了,那么后面的客户端和服务器进行的加密通信就没有用处了,因为黑客拿到了密钥,也能解密客户端和服务器通信的内容。如果我们对密钥进行对称加密的话,那么就仍然需要一个“密钥的密钥”,这就陷入了循环,所以方案1是行不通的。
通过上面对非对称加密机制的介绍。当只使用非对称加密时,如果服务器先把公钥S以明文方式传输给浏览器,之后浏览器向服务器传数据前都先使用这个公钥S将数据加密为密文后传输,这样看从客户端到服务器的信道似乎是安全的,因为只有服务器有相应的私钥将数据进行解密。但是从服务器到浏览器的信道无法保证其安全。如果服务器用它的公钥加密数据传输给浏览器,但是因为浏览器没有私钥,所以无法对数据进行解密。而如果服务器用它的私钥加密数据传输给浏览器,那么虽然浏览器可以用公钥将数据解密,但是因为公钥是刚开始通过明文传输给浏览器的,若这个公钥被中间人劫持到了,那么这个中间人也能用该公钥解密服务器传输的数据了。所以方案2是行不通的。
服务器拥有公钥S与对于的私钥S’,客户端拥有公钥C与对应的私钥C’。然后客户端和服务器交换公钥。
当客户端给服务器发送信息:先用公钥S对数据进行加密,再发送,这个数据只能由服务器的私钥S’进行解密。
当服务器给客户端发送信息:先用公钥C对数据进行加密,再发送,这个数据只能由客户端的私钥C’进行解密。
这样的方案看着虽然也很合理,但是我们前面说了非对称加密的最大的缺点就是速度很慢,如果客户端和服务器都使用非对称加密的话,那么通信速度会更慢了,即会花很多的开销在加密和解密上。
服务器具有非对称公钥S和私钥S’。客户端发起https请求给服务器,然后服务器将公钥S返回给客户端,客户端在本地生成对称密钥X,然后将密钥X通过公钥S进行加密后发送给服务器。服务器拿到密文通过私钥S’进行解密得到对称密钥X。后序客户端和服务器就可以通过对称密钥X进行通信了,由于对称密钥X只有客户端和服务器两个主机知道,其它主机/设备不知道对称密钥X。这样虽然中间人可以截取传递密钥X的密文,但是因为中间人没有私钥S’,所以无法对密文进行解密得到对称密钥X。如果没有对称密钥X那么中间人也就不能解密通过密钥X加密后的密文了。并且这个方案刚开始使用非对称加密进行密钥协商,然后后面的客户端和服务器通信就使用对称加密了,所以速度也会比较快。
上面的方案4虽然看似已经可以安全通信了,但是如果中间人在刚开始就进行了攻击,即在最开始握手协商的时候就进行了,那么方案4就还存在安全问题。
例如下面的情况。
1.服务器具有非对称加密算法的公钥S,私钥S’。
2.中间人具有非对称加密算法的公钥M,私钥M’。
3.客户端向服务器发起请求,服务器明文传送公钥S给客户端。
4.中间人劫持数据报文,提取公钥S并保存好,然后将被劫持报文中的公钥S替换为自己的公钥M,并将伪造报文发送给客户端。
5.客户端收到报文,提取公钥M(客户端当然不知道公钥被更换过了),客户端形成对称密钥X,用公钥M加密X,形成报文发送给服务器。
6.中间人劫持报文,直接用自己的私钥M’进行解密,得到对称密钥X,再用曾经保存的服务器公钥S加密对称密钥X,然后将报文发送给服务器。
7.服务器拿到报文后,用自己的私钥S’解密,得到对称密钥X,服务器此时也不知道对称密钥X已经被中间人拿到了。
8.服务器和客户端双方开始采用对称密钥X进行对称加密,然后通信。但是因为中间人有对称密钥X,所以双方的通信密文中间人都可以解密得到明文,这样中间人就可以劫持数据,进行窃听甚至修改数据,这些操作都是可以做到的。
上面的问题本质就是客户端无法确定收到的含有公钥的数据报文就是目标服务器发送过来的。即如果客户端可以通过一些方法验证收到的公钥是目标服务器发送过来的话,那么上面的问题就解决了。因为如果客户端验证收到的公钥不是目标服务器发送过来的,而是中间人发送的,那么客户端就不会将对称密钥发送过去,这样就不会有下面中间人监听的情况了。只有当客户端验证收到的公钥是目标服务器发送的时才进行对称密钥的发送。
服务器在使用HTTPS协议前,需要向CA(Certificate Authority)机构申领一份数字证书,数字证书里含有证书申请者信息、公钥信息等。服务器把证书传输给浏览器,浏览器从证书里获取公钥就行了,证书就如身份证,证明服务器公钥的权威性。
这个证书可以理解成是一个结构化的字符串,里面包含了以下信息:
- 证书发布机构
- 证书有效期
- 公钥
- 证书所有者
- 签名
- …
需要注意的是:申请证书的时候,需要在特定平台生成一对密钥对,即公钥和私钥。这对密钥对就是用来在网络通信中进行明文加密以及数字签名的。
其中公钥会随着CSR文件一起发给CA机构进行权威认证,私钥服务端自己保留,用来后续进行通信(其实主要就是用来交换对称密钥)。
当服务端申请CA证书的时候,CA机构会对该服务端进行审核,并专门为该网站形成数字签名,过程如下:
1.CA机构拥有非对称加密的私钥A’和公钥A。
2.CA机构对服务端申请的证书明文数据进行hash,形成数据摘要。
3.然后对数据摘要用CA私钥A’加密,得到数字签名S。
服务端申请的证书明文和数字签名S共同组成了数字证书,这样一份数字证书就可以颁发给服务端了。
验证数字证书的过程就是通过hash函数将数字证书中的证书明文形成散列值。然后再使用CA机构的公钥A将数字证书中的数字签名进行解密得到散列值。如果这两个散列值相同那么说明这个数字证书是真的,即是通过CA机构颁发的具有权威的数字证书。为什么这样验证就能得到数字证书是真的呢?因为首先证书明文通过hash函数形成的数据摘要是唯一的,即散列值是唯一的。然后这个数据摘要经过CA机构的私钥A’进行加密,因为其它人没有CA机构的私钥A’,所以也无法修改数字签名后再进行加密。所以如果有黑客修改了数字证书的证书明文或者数字签名的话,那么两个散列值就不相同,那么这个数字证书就不是可靠的了。
在客户端和服务器刚建立连接的时候,服务器给客户端返回一个数字证书,证书包含了之前服务端的公钥,也包含了网站的身份信息。
当客户端获取到这个数字证书之后,会对数字证书进行效验(防止证书是伪造的)
- 判定证书的有效期是否过期。
- 判定证书的发布机构是否受信任(操作系统中已内置的受信任的证书发布机构。
- 验证证书是否被篡改:从系统中拿到该证书发布机构的公钥,对数字证书中的签名进行解密,得到一个hash值(称为数据摘要),记为hash1。然后将数字证书的证书部分通过hash函数计算出hash值,记为hash2。对比hash1和hash2是否相等,如果相等,那么这个数字证书是没有被篡改过的,即这个服务器发送过来的公钥是可以使用的。
中间人有没有可能篡改证书?
如果中间人篡改了证书的明文,即修改证书的公钥等数据,由于中间人没有CA机构的私钥A’,所以无法将修改后的证书明文经过hash函数之后形成的hash值进行私钥A’加密形成签名。那么也就没有办法对篡改后的证书形成匹配的签名。这样如果中间人强行篡改证书数据,客户端收到该证书后会发现证书明文形成的hash值和签名解密后形成的值不一样,那么就说明证书的数据被篡改了,即证书不可信,从而终止向服务器传输信息,防止信息泄露给中间人。
中间人整个调用证书?
因为中间人没有CA机构的私钥,所以无法制作假的证书,因为浏览器只使用内置的CA机构的公钥来对证书中的签名做解密。而当公钥进行解密时,只能使用私钥来进行加密,如果中间人使用自己的私钥来对假证书的签名做加密,那么浏览器依旧使用CA机构的公钥来对证书的签名做解密,所以是无法将签名进行解密的。所以中间人只能向CA机构申请真证书,然后用自己申请的证书进行调包。这样做确实能做到证书的整体调包,但是证书中包含了域名等服务端认证信息,如果整体调用,客户端就能识别出来当前证书上的域名与自己要访问的域名不同,然后就发现了这个网站不是自己要访问的网站。并且我们需要知道,因为中间人没有CA机构的私钥,所以对任何证书的内容都无法进行合法修改,包括自己的证书,所以中间人修改自己证书上的域名等信息也是不可能的。
下面就是HTTPS的完整流程。
HTTPS工作过程中涉及到的密钥有三组:
其实上面的证书认证这一切的关键都是围绕这个对称加密的密钥的,其它的机制都是辅助这个密钥工作的。
第二组非对称加密的密钥是为了让客户端把这个对称密钥传给服务器。
第一组对称加密的密钥是为了让客户端拿到第二组非对称加密的公钥。