前提知识准备
https做了什么
HTTPS 也是⼀个应⽤层协议. 是在 HTTP 协议的基础上引⼊了⼀个加密层.
HTTP 协议内容都是按照⽂本的⽅式明⽂传输的. 这就导致在传输过程中出现⼀些被篡改的情况.
我们用户的很多个人信息都是在http协议的请求和相应中的,我们之前也知道,我们把数据传输给对方时,通常并不是直接传输中,中间会存在很多 类似中间人性质的点,比如网络运营商或者黑客或者路由器这些。在这些中间人的眼里,我们小白的个人信息等于是在裸奔,他们轻而易举的就可以窃取我们的信息甚至篡改我们的信息。 因此,我们需要对我们的信息进行加密。
我们之前学过http,其实http就是加了一层软件层,数据要发送的时候就会经过这层被加密,对方收到之后再经过这层软件进行解密。这就是https所做的事情。
关于加密和解密
加密是什么?
加密就是将明文通过密钥来生成密文。
解密就是密文通过密钥来生成明文。
加密解密到如今已经发展成⼀个独⽴的学科: 密码学。
⽽密码学的奠基⼈, 也正是计算机科学的祖师爷之⼀, 艾伦·⻨席森·图灵。
为什么要加密?
以前曾发生过臭名昭著的"运营商劫持"事件
我们知道,网络运营商就是来给我们提供网络服务的,并且他们也是中间人性质的。
以前我们下载一些软件的时候,明明我们要下载的是A软件,但是当我们点击下载按钮的时候,A软件的下载链接被替换成了B软件的下载链接。
由于我们通过⽹络传输的任何的数据包都会经过运营商的⽹络设备(路由器, 交换机等), 那么运营商的⽹络设备就可以解析出你传输的数据内容, 并进⾏篡改。
点击 "下载按钮", 其实就是在给服务器发送了⼀个 HTTP 请求, 获取到的 HTTP 响应其实就包含了该 APP 的下载链接. 运营商劫持之后, 就发现这个请求是要下载天天动听, 那么就⾃动的把交给⽤⼾的响应给篡改成 "QQ浏览器" 的下载地址了。
所以:因为http的内容是明⽂传输的,明⽂数据会经过路由器、wifi热点、通信服务运营商、代理服务器等多个物理节点,如果信息在传输过程中被劫持,传输的内容就完全暴露了。劫持者还可以篡改传输的信息且不被双⽅察觉,这就是 中间⼈攻击 ,所以我们才需要对信息进⾏加密。
在互联网上,直接使用明文进行传输是一件非常危险的事情。
现在https非常的流行,就是因为数据传输安全可靠。那么关于安全性这个问题其实是有点说法的。假设有一个密钥会有黑客们去攻破,当攻破它的成本 > 黑客攻破这个密钥的收益 时,那么这个密钥就是安全的。并且像ssl这样权威的官方加密解密方案,有很多用户去使用,那么也就有很多黑客去攻破,所以ssl也是需要不断的维护去更新的。
常见的加密方式
对称加密
采⽤单钥密码系统的加密⽅法,同⼀个密钥可以同时⽤作信息的加密和解密,这种加密⽅法称为对
称加密,也称为单密钥加密,特征:加密和解密所⽤的密钥是相同的
常⻅对称加密算法(了解):DES、3DES、AES、TDEA、Blowfish、RC2等
特点:算法公开、计算量⼩、加密速度快、加密效率⾼
对称加密其实就是通过同⼀个 "密钥" , 把明⽂加密成密⽂, 并且也能把密⽂解密成明⽂。
举个例子就是我们的异或操作(^),只要用户和服务器双方规定使用特定的一个数对数据进行异或操作,用户和服务器就可以根据这个规则进行加密的通信。
非对称加密
需要两个密钥来进⾏加密和解密,这两个密钥是公开密钥(public key,简称公钥)和私有密钥
(private key,简称私钥)。
常⻅⾮对称加密算法(了解):RSA,DSA,ECDSA。
特点:算法强度复杂、安全性依赖于算法与密钥但是由于其算法复杂,⽽使得加密解密速度没有对
称加密解密的速度快。
⾮对称加密要⽤到两个密钥, ⼀个叫做 "公钥", ⼀个叫做 "私钥"。
公钥和私钥是配对的. 最⼤的缺点就是运算速度⾮常慢,⽐对称加密要慢很多。
明文通过公钥变成密文,然后这个密文就只能通过私钥来解释成明文。
也可以反过来,明文也可以通过私钥来变成密文,然后可以通过公钥来解释成明文。
数据摘要 && 数据指纹
数字指纹(数据摘要),其基本原理是利⽤单向散列函数(Hash函数)对信息进⾏运算,⽣成⼀串固定⻓度 的数字摘要。数字指纹并不是⼀种加密机制,但可以⽤来判断数据有没有被窜改。
摘要常⻅算法:有MD5、SHA1、SHA256、SHA512等,算法把⽆限的映射成有限,因此可能会有碰撞(两个不同的信息,算出的摘要相同,但是概率⾮常低)
摘要特征:和加密算法的区别是,摘要严格意义不是加密,因为没有解密,只不过从摘要很难反推
原信息,通常⽤来进⾏数据对⽐。
这里可以拿我们之前说过的Cookie那里举例,服务器有那么多用户,但是又必须保证sessionID具有唯一性。因为用户名是唯一的,那么服务器就可以根据用户名通过MD5算法,来生成一个唯一的sessionID,也就是数据指纹,来进行管理。
这里可以谈一谈像百度网盘秒传的功能。我们平常在百度网盘上上传一个游戏或者一部电影,大概好几个G。可能要个十几分钟。但是有时候我们上传的时候,有一个秒传的功能,顾名思义就是一秒就给你上传了,好几个G甚至几十个G,一秒钟就上传了,这莫不是什么黑科技吗?其实这里就是运用了数据指纹的原理,我们上传的资源,在百度网盘的服务器上可能别人也传了一份一模一样的资源,我们资源首先经过算法(比如MD5算法)生成具有唯一性的数据指纹之后,先在全服务器上搜索,看有没有一样的数据指纹,如果是一样的,那么就不需要再傻傻的上传一份一模一样的资源了,直接给你安排一个软链接,指向这个资源即可,既方便用户,还能节省服务器资源。
不过这样的算法本质上一个哈希的过程,哈希是不可逆的。所以像MD5这样的算法其实不能算加密算法,因为它的转换是不可逆的。
HTTPS原理的探究
在了解了加密方式后,我们可以探究一下,HTTPS是采取怎样的方案来保证数据的安全呢?
1. 只使用对称加密
我们可以规定服务器和客户端都使用哪一个密钥,这样的话黑客们就算拿到我们的请求报头也是经过加密的,无法窃取或者篡改信息。
但是这样的话,暴露的问题也非常明显,那就是用户有千千万,如果每个用户的密钥都是相同的,那么黑客也很容易就拿到了,但如果每个用户的密钥都不同,那么服务器还要维护每个用户客户端和密钥之间的关系,也很麻烦,我们也总不能把密钥放在响应中给用户吧。
所以这种方案不行
2.只使用非对称加密
假设我们让用户拥有一份公钥,服务器拥有私钥,那么用户发送过去的数据经过公钥加密,是安全的,但是服务器发过来的数据该怎么办呢?经过私钥加密的数据,直接用公钥就可以解密了,黑客想拿到公钥又不难。
所以这种方案也是凑数的,不行。
3.双方都使用非对称加密
比如我们设置客户端有公钥C私钥C',服务器有公钥S和私钥S'。
首先客户端和服务端可以先交换公钥,这样的话客户端通过公钥S加密发送给服务器,服务器用私钥S'解密;同理,服务器用公钥C加密,然后客户端用私钥C'解密。
这样看起来是安全的,但是频繁的使用非对称加密会导致效率非常低。
并且其实也是存在安全问题的,在讨论方案4后就知道了。
4.非对称加密+对称加密
先说流程,首先是服务器具有非对称密钥公钥S和私钥S',客户端还没有密钥。
第一次客户端向服务器发起请求,服务器第一次响应时先把公钥S传给客户端,然后客户端在本地生成 一个对称密钥C,然后对密钥C使用公钥S进行加密再发送请求给服务器。然后服务器通过私钥S'进行解密后,就能拿到由客户端生成的对称密钥C。 从此双方就用密钥C来进行通信。
这样的话只有第一次是使用非对称密钥通信的,之后都是使用对称密钥通信的。这样就解决了效率问题。
并且中间人也无法得知密钥C,这样通信就安全了吗?
其实这种方案已经很接近正解了,但是这个方案已经被攻破了:
中间人同样可以拿一对非对称密钥,公钥M和私钥M'。具体攻破方法是这样的:
在第一次响应给客户端返回密钥S的时候,中间人就将响应报头截取,并将密钥S替换成密钥M,这样客户端就拿着M密钥来给生成的密钥C进行加密,这样将加密好的C发给服务器的时候,中间人就可以轻而易举的通过私钥M'先解密来获取密钥C,在获取到密钥C之后,再用S公钥来给数据加密,这样服务器拿到数据之后,依旧是用私钥S'解密来获取密钥C,之后双方就用密钥C来通信了,殊不知中间人手里已经拿到密钥C笑开花了。
因此方案4看似很不错,但是也还是存在安全问题,接下来谈正解方案5之前,还需要再来谈谈证书这个概念。
证书
对于方案4,其实只有一个缺陷:就是客户端无法得知,相应中的公钥是否合法。带着这个问题我们再来看证书是如何解决这个问题的。
CA认证
服务端在使⽤HTTPS前,需要向CA机构申领⼀份数字证书,数字证书⾥含有证书申请者信息、公钥信息等。服务器把证书传输给浏览器,浏览器从证书⾥获取公钥就⾏了,证书就如⾝份证,证明服务端公钥的权威性。
CA机构是全球的权威性机构,通过证书解决问题就好比我们在大街上走路,突然来了一名警察要对我们的身份进行验证,就常识来说,警察肯定是需要一些具有权威性的证件来证明我们的身份,比如身份证。那么身份证是有我们中国政府颁发的,因此具有权威性,并且如果有人胆敢对身份证进行造假或者篡改信息是会被追究法律责任的,所以一般不会有人做这样的事情。同理,通过证书来解决这个问题用的是类似的思想。先看证书
一份合法证书一般是由签名 和明文信息组成的。
明文信息
明文信息很多都是必填的,并且是可以法律溯源的,比如申请者或者申请机构,还有具有唯一性的,你要申请的证书的域名等等。
但是在明文信息中,还有一个很重要的信息就是 公钥 !这个公钥就是将来服务器和客户端之间会使用到的那个公钥,服务器在申请证书的时候要把公钥提供给CA机构。这样在方案4的基础上,服务器第一次给用户的响应就不再仅仅是公钥了,而是一份证书,这个证书里面包含了公钥。
大致的流程就是,服务器首先需要先申请证书--》等待审核后--》再签发证书给服务器--》在客户端第一次请求返回的响应中,把证书给客户端--》客户端进行验证--》然后再是密钥的协商。
关于证书,可以理解为是一个结构化的字符串,里面包含了证书发布机构,证书有效时间,公钥等信息。
不过还需要注意的是,我们在申请证书之前,还需要生成一个SRC文件,服务器的公钥会伴随着SRC文件一起给CA机构进行申请。网上也有一些SRC文件的在线生成。对应的私钥CA'生成后也是交给服务器保管的。
接下来就需要理解数据签名了
数据签名
再说一次,证书是由签名和明文信息组成的,明文信息很好理解,这个签名有什么用呢?
首先,签名的形成是基于非对称加密算法的。这里所用到的公钥和私钥跟之前的完全没关系。
先看证书的形成
签名是将明文数据,通过散列函数(比如DM5算法,sha算法这些)生成了一份数据摘要(也就是数据指纹), 然后再将这份数据摘要用CA机构的私钥CA'进行加密后,与明文数据放在一起,便形成了证书。
需要特别注意,这里对数据摘要加密的是CA机构的私钥CA'!
证书形成后,那么服务器就可以发送给客户端了,客户端就会验证证书
验证的方法是:将明文数据使用同样的散列函数,生成一份数据摘要。然后对于签名使用CA机构的公钥CA进行解密,也得到一份数据摘要。最后将两份摘要进行比对,如果相等,则说明证书没有被篡改;反之,证书被篡改了!
但是,既然签名可以被公钥CA解密,那么作为中间人,能不能把明文数据修改后,再重新生成一份签名呢?
这就是证书解决这个问题最巧妙的地方了,签名是由私钥CA'加密的,如果中间人再想重新生成一个签名,那么他该用什么方式再加密呢?私钥CA'只有CA机构拥有,为什么说证书是权威的,因为只有CA机构拥有私钥!所以CA机构才有资格发证书!
所以至少在这里,我们就不担心证书被篡改的问题了。所以方案5大家也能猜到了
5.非对称加密+对称加密+证书
所以,在方案4的基础上,第一次服务器给客户端的响应就不再仅仅是一份公钥了,而是一份具有权威性的证书,公钥在证书里面,然后客户端在验证了证书的合法性之后,再用里面的公钥,将本地生成的对称密钥进行加密,再发回给服务器。
关于客户端进行的证书验证:
一般会验证证书的有效时期,再看看证书的发布机构是否受到信任,还要要验证证书是否被篡改。
一旦发现有异常,那么客户端就会终止向服务器再发起请求,或者警告用户证书存在问题。
很多网站的权威性的证书,在我们下载浏览器的时候,就已经被内置在浏览器当中了,我们用户也可以手动添加一些证书。
在浏览器的设置里面,可以找到 管理证书 的选项,来查看证书的各种信息。
比如我们还可以看这个签名是用什么算法生成的。
再谈谈HTTPS协议及总结
HTTPS的安全性
现在我们知道了,信息的安全主要是HTTPS通过加入权威性的证书来保障的。篡改证书现在看来是行不通的,那么有没有人会直接把整个证书掉包呢?
还真有,原理就是一些违法分子通过申请CA证书,申请到CA证书之后,用自己的CA证书给别人的CA证书进行了掉包。就比如以前我们说有些网站是钓鱼网站,甚至还有政府的钓鱼网站,我们点击进去之后,发现页面与官方的网站非常的相似,但其实是钓鱼网站模仿做出来的,它们先是收集我们的请求,经过一些处理之后,再发送给官方网站,期间就有可能窃取了我们的个人信息。
但是我们之前也说过, 这种权威性的机构之所以权威,还有一点就是申请人提交的信息是可以进行法律溯源的,但这就不是我们的范畴了,而是网警的范畴了。
所以掉包是可行的,但是已经不是我们要关心的了。
还有就是黑客们可以直接从客户端入手,比如植入有类似浏览器功能的一些病毒程序,使客户端对证书的验证在这个病毒程序上验证。
关于签名
有些人可能会说,为什么我们不直接将公钥S使用私钥CA'加密后,直接发给客户端呢?中间人照样不能篡改。确实可以,但是存在效率问题,通过DM5算法生成的数据摘要一般就16或32字节,如果要加密的明文太长了,会影响加密的效率,也会影响解密的时间。
总结
HTTPS工作中,涉及的密钥有三组:
第一组(非对称加密):用于验证证书是否被篡改,服务器持有私钥(私钥在形成SRC文件与申请证书时获得),客户端持有公钥(浏览器包含了可信任的CA机构有哪些,并持有对应的公钥)。
第二组(非对称加密):用于协商生成对称加密的密钥。
第三组(对称加密):客户端和服务器后续的传输的数据就都通过这个对称密钥进行加密和解密。