之前我们已经给大家介绍了HTTP协议以及它的Cookie,Session等概念,谈论到了HTTP的局限性就是安全性存在严重不足,虽然我们有着Session与Cookie为传输信息的安全做了一个补偿,但是在实际中,仍然存在较大的风险。
尤其是我们以POST方式进行信息传输时,我们的信息虽然存储在正文,但是仍然可以被各种软件所获取,而获取到的内容,是可以直接看到我们的正文的。因为HTTP协议的内容,都是按照文本的方式进行铭文传输的。
而所谓的HTTPS,就是在HTTP协议的基础上,再加了一个加密层。
那么今天我们就继续来学习一下HTTPS原理,看我们的HTTPS是如何解决这个安全问题的。
加密就是把 明文(要传输的信息)进行一系列的变换,生成密文。
解密就是把密文再进行一些列的变换,还原成明文
在这个加密和解密的过程中,往往需要一个或多个中间的数据,辅助进行这个过程,这样的数据我们称为密匙
大家听说过运营商劫持吗?
就是当我们在浏览器中点击一个下载链接,比如说是下载QQ音乐。正常的来说,我们的下载效果应该是点击下载链接后,浏览器就会开始给我们下载QQ音乐。但如果我们的通过网络传输的数据包,经过运营商的网络设备(路由器,交换机等),那么运营商的网络设备就可以解析出我们传输的内容,并进行篡改。
所以就会强制让我们下载应用宝啊,或者其他运营商想让你下载的软件。
HTTP的内容都是明文传输的,明文数据会经过路由器、WiFi热点、通信服务运营商、代理服务器等多个物理节点,如果信息在传输过程中被劫持,传输的内容就完全暴露了。劫持者可以篡改传输的信息且不被双方察觉,这就是中间人攻击,所以我们才需要对信息进行加密。
并且不止运营商可以劫持,其他的黑客也可以用类似的手段来进行劫持,用来窃取用户的私密信息,或者篡改内容。
所以我们需要对传输的数据进行加密。
我们主要有两种加密方式:对称加密与非对称加密
对称加密采用单匙密码系统的方法,同一个密匙可以同时用作信息的加密与解密,这种加密方法称为对称加密,也被称为单密匙加密。他的最主要特征就是加密和解密所用的密匙是相同的
常见的对称加密的算法有(了解一下就行):DES,3DES,AES,TDEA等。
特点:算法公开,计算量小,加密速度快,加密效率高。
对称加密之所以叫对称加密,是因为它的加密与解密是通过同一把密匙,通过这个密匙,可以把明文加密成密文,也可以把密文解密成明文。
需要有两个密匙来进行加密与解密,这两个密匙,一个是公开的密匙,简称公匙,另外一个是私有密匙,简称私匙。
常见非对称算法有:(仅了解)RSA,DSA,ECDSA等。
特点是:算法强度高,安全性依赖于算法与密匙,但是由于其算法复杂,使得其加密速度没有对称加密解密快。
为什么要用两把密匙呢?对称加密与非对称加密有什么区别呢?
首先,对称加密需要通信双方都知道那个唯一的密匙,这是他们两个加密解密的前提条件。
而非对称加密由于有两个密匙,所以加密解密的方法多种多样。
我们既可以通过公匙对明文进行加密变成密文,随后用私匙将密文解密成明文。
也可以先通过密匙将明文加密为密文,然后加密文解密为明文。
非对称加密的数学原理比较复杂,涉及到一些到数论相关的知识忙着哩举一个最简单的生活上的例子: A要给B一些重要文件,但是B可能不在,于是A和B提前作出约定:
B说:我桌子上有一个盒子,然后我给你一把锁,你把文件放盒子里用锁锁上,然后我回头拿着钥匙开锁取文件。
在这个场景中,这把锁就相当于公匙,钥匙就是私匙,公匙给谁都可以,随便一个人都可以去锁上,但是私匙只有B自己持有,持有私匙的人才能进行解密操作。
数据摘要是什么呢?
数据摘要,也常被称为哈希值或数字指纹,是一段数据(比如一个文件、一段文字、一部电影)经过一种特殊数学函数计算后,得到的一串固定长度的、唯一的“身份证号码”。
数字指纹并不是一种加密机制,但可以用来判断数据有没有被篡改。
本质上是对一个大文件,以哈希类算法的方式提取出一个固定长度的摘要,且保证,如果大文件中哪怕一个字节被改了,那么同样算法得出的结果绝对不同。
这个一般用于检验文件有无被改过,两边用同一算法对同一文件取摘要对比结果即可。
产生数据摘要的数学函数叫哈希函数。一个优秀的哈希函数必须具备以下三个特点:
185f8db32271...。你今天算、明天算、在北京算、在纽约算,结果都一样。
185f8db32271...,你无法知道原始数据是 “Hello” 还是别的什么。就像你无法从一盘菜的香味完美还原出它的完整食谱。
185f8db32271fe...
b4c3e... (完全不同!)
myPassword123。
SHA256("myPassword123")。
我们刚刚给大家讲了HTTPS的两个加密方式,对称加密与非对称,那么我们就有几种方案可以进行信息的通信呢?
首先我们来试试第一方案:只使用对称加密
如果通信双方都各自持有同一个密钥K,且没有别人知道,这两方的通信安全当然是可以被保证的(除非密钥被破解)

并且由于我们使用的是对称加密,整个加密与解密的过程十分迅速,但是这个具有一个很致命的缺点
对称加密的前提是通信双方必须拥有相同的密钥。那么问题来了:在第一次通信中,如何把这个密钥安全地告诉对方?
想象一下,你要和一个陌生人通过明信片通信,但你们约定好以后都用一种密码写信。你首先得把密码本寄给他吧?但如果你把密码本直接用明信片寄过去,邮递员(攻击者)不就能看到密码本了吗?这就是“密钥分发”困境。
但是如果直接把密钥明文传输,那么黑客也就能获得密钥了,此时后续的加密操作就形同虚设了.
因此密钥的传输也必须加密传输**!
但是要想对密钥进行对称加密,就仍然需要先协商确定一个"密钥的密钥".这就成了"先有鸡还是先有蛋"的问题了.此时密钥的传输再用对称加密就行不通了.
我们说一个非对称加密,需要一个公匙K,以及一个私匙X,公匙无论泄不泄露,都无所谓,但是私匙绝对不能泄露。
鉴于非对称加密的机制,如果服务器先把公钥以明文方式传输给浏览器,之后浏览器向服务器传数据前都先用这个公钥加密好再传,从客户端到服务器信道似乎是安全的(有安全问题*)**,因为只有服务器有相应的私钥能解开公钥加密的数据。

如图,我们先申请获取公钥,此后公钥就会被发回客户端,此后我们就能通过在客户端进行公钥加密,在服务端进行私钥解密来进行信息交流。
但是服务器到浏览器的这条路怎么保障安全?
如果服务器用它的私钥加密数据传给浏览器,那么浏览器用公钥可以解密它,而这个公钥是一开始通过明文传输给浏览器的,若这个公钥被中间人劫持到了,那他也能用该公钥解密服务器传来的信息了。
并且,由于非对称加密算法(如RSA、ECC)的核心数学运算(如大数质因数分解、椭圆曲线离散对数)非常复杂且耗时, 通信速度极慢,用户体验无法接受。
所以这个只能看似可以,但实际上肯定不会用这种方式。
这个方案确实解决了保密性和身份认证问题,甚至提供了客户端的不可否认性。
尽管在理论上安全,但将其用于所有网站访问(如浏览新闻、看视频)是不现实的。
和之前分析的一样,非对称加密速度慢。现在双向的所有通信都承受这种性能开销,而不仅仅是服务器到客户端。服务器的计算压力更大,客户端的体验也会变得非常卡顿。加载一个现代网页需要数百次请求响应,每次都要进行非对称加密解密,速度是无法接受的。
并且其还有一个更加致命的问题,那就是密钥管理和分发
密匙与公匙的问题不在于服务器,而在于客户端(亿万普通用户)。
所以,这个方案也会被我们否定掉。
这个方案是如何工作的呢?
由于对称加密的效率比非对称加密的效率高很多,所以我们在开始阶段协商密匙的时候使用非对称加密,后面的信息传输就只使用对称加密。如此一来,就能解决我们的效率问题。

我们在现在的https协议中,最长使用的就是我们刚刚说的第四种方案,也就是对称加上非对称加密的方式。
但是这个方式,就是完美的最佳的方式了吗?
并不是这样的,世界上没有绝对安全的加密方式。
我们的第四种方案看似很安全,实际上还是存在漏洞。
客户端获取到公钥 S 之后,对客户端形成的对称秘钥 K 用服务端给客户端的公钥 S 进行加密,中间人即使窃取到了数据,此时中间人确实无法解出客户端形成的密钥 K,因为只有服务器有私钥 S’
但是中间人的攻击,如果在最开始握手协商的时候就进行了,那就不一定了,你凭什么保证你一开始服务端送你的公匙S就一定是服务端给你的?
上面的攻击方案,同样适用于方案 2,方案 3,这个就是我们所说的中间人攻击。
那么问题本质出在哪里了呢?
:客户端无法确定收到的含有公钥的数据报文,就是⽬标服务器发送过来的!
刚才我们讲到,即使使用了非对称加密,依然无法完全避免中间人攻击。其核心漏洞在于:
客户端(浏览器)无法确认收到的公钥,到底是不是来自真正的目标服务器,还是来自一个伪装的中间人。
这就好比在一个漆黑的房间里,有人对你喊:“我是张三,我的电话号码是138…!” 你无法确定说话的人是不是真张三,还是李四在冒充张三。
为了解决这个“身份认证”的根本问题,我们需要一个在黑暗中所有人都信任的权威公证人。这个公证人就是证书颁发机构(CA),它颁发的“数字身份证”就是CA证书(通常指SSL/TLS证书)。CA证书的出现,就是为了给网站的公钥提供一个可信的、防篡改的“担保”。
我们之前在上面讲过数字摘要的概念,大家还记得吗?
我们的CA证书就运用的是这个原理,在此之前,我们首先要知道CA的组成部分。
那么,我们的CA证书是怎么样组成的呢?
这部分信息是未加密的,任何拿到证书的人都能直接读取。主要包括:
www.google.com。这是验证“这个证书是给谁的”最关键的依据。
这是CA证书的灵魂,是防止篡改和伪造的关键。它不是一段独立的文字,而是一个加密后的结果。
这个签名是如何生成的?(由CA在签发时完成)

这个数字签名是CA机构用自己的私匙加密后的一种产物,需要通过公匙来进行解密获取数字前面。
虽然公匙很容易被获取,也就代表着我们的数字签名容易被人直接知晓,但是他人也无法修改我们的数字签名,因为中间人替换的数字签名必然要加密,而这个加密不可能用CA机构自己持有的私匙。由于非对称加密的特性,倘若中间人用自己的私匙进行加密,此时发送给客户端,客户端只会使用CA机构发出来的公匙进行解密,导致解密失败,于是就能得知我们的数据被人篡改过。
可能有同学会好奇,你凭什么使用的CA机构的公匙就一定是CA机构的?这是因为你的浏览器(如Chrome、Firefox、Safari)或您的操作系统(Windows、macOS、Linux)在出厂时,就内置了一个名为 “信任根证书存储” 的列表。
bank.com)时,它会沿着证书链向上验证,直到找到签发这个证书的根CA。
如果中间人不能攻破我们的数字签名,那么他对我们证书中其他的明文信息的修改就会直接不攻而破。
因为数字签名的有确定性,相同的数据通过同一个哈希算法得出的数字摘要一定是一样的。同一个道理,如果你更改了正文部分的任意数据信息,那么客户端自己通过该哈希函数算出的数字摘要结果就会不同,从而得知被篡改了。
所以我们就保证了证书中正文的安全性。而证书中的正文,就包含了我们的服务端的公匙,所以我们就可以保证用户端获取的服务端公匙一定就是真的。
至此,客户端就可以生成自己的对称密匙,并通过服务端的公匙进行加密,这个内容只有服务端的私匙可以进行解密,所以就可以确保我们的服务端获取到对称密匙,从此,我们的服务端与客户端就可以通过对称密匙进行对称加密了!!!!



Client Hello消息,其中包含:自己支持的TLS版本、支持的密码套件列表、以及一个客户端随机数。Server Hello消息,内容包括:双方协商一致的TLS版本、选定的密码套件、一个服务器随机数,以及至关重要的SSL证书。此证书包含服务器的公钥。Finished消息,用刚生成的会话密钥加密,确认握手过程安全无误。至此,安全通道建立。HTTPS 工作过程中涉及到的密钥有三组.
第一组(非对称加密): 用于校验证书是否被篡改. 服务器持有私钥(私钥在形成 CSR 文件与申请证书时获得), 客户端持有公钥(操作系统包含了可信任的 CA 认证机构有哪些, 同时持有对应的公钥). 服务器在客户端请求时,返回携带签名的证书. 客户端通过这个公钥进行证书验证, 保证证书的合法性,进一步保证证书中携带的服务端公钥权威性。
第⼆组(非对称加密): 用于协商生成对称加密的密钥. 客户端用收到的 CA 证书中的公钥(是可被信任的)给随机生成的对称加密的密钥加密, 传输给服务器, 服务器通过私钥解密获取到对称加密密钥.
第三组(对称加密): 客户端和服务器后续传输的数据都通过这个对称密钥加密解密.
其实一切的关键都是围绕这个对称加密的密钥. 其他的机制都是辅助这个密钥工作的.