关于HTTP的详细内容见 计算机网络系列 -- HTTP
本文大部分内容参考于 彻底搞懂HTTPS的加密原理 这篇文章
HTTPS 的定义
HTTPS 是以安全为目标的 HTTP 通道,在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性。HTTPS 在HTTP 的基础下加入 SSL,HTTPS 的安全基础是 SSL,因此加密的详细工作就由 SSL 协议来完成
HTTPS协议 = HTTP协议 + SSL协议,在HTTPS数据传输的过程中
- 利用
SSL 协议
对数据进行加密
和解密
- 利用
HTTP 协议
对加密后的数据
进行传输
由此可以看出 HTTPS 是由 HTTP 和 SSL 一起合作完成
的
SSL 的定义
SSL 及其继任者 TLS 是为网络通信提供一种能保证数据安全及数据完整性的安全协议。TLS 与 SSL 在传输层与应用层之间对网络连接进行加密
HTTPS 对 HTTP 的改进
HTTPS 对 HTTP 的改进体现在三个点上:
- 数据安全:采用
混合加密
技术,中间者无法直接查看
明文内容 - 身份验证:通过
证书
认证客户端访问的是自己的
服务器 - 数据完整性:防止传输的内容被中间人
冒充
或者篡改
例如:通过抓包可以看到数据不是明文传输
HTTPS 是如何保证安全性的
- HTTPS 的安全性在于它是采用非对称加密和对称加密两种方案
混合
的方式进行数据传输的- 首先公钥、私钥都在服务器那里,浏览器请求URL就是
请求服务器给个公钥
,浏览器用公钥加密,服务器私钥解密,这个过程是在传输密钥- HTTPS 的安全性关键取决于非对称加解密过程的安全性,浏览器是通过查
数字证书的颁发者
的信息和服务器的信息做对比,验查是否被调包- 浏览器还通过
数字签名
去映射出
数字证书的原始内容和拿到的证书内容做对比,验查是否被篡改- 一旦发现证书被调包/篡改,都终止交易,不传密钥
接下来我们从【密码学】、【对称加密】、【非对称加密】、【数字证书】、【数字签名】层层深入,最终总结出【SSL 握手的全过程】,从而得出 HTTPS 是具体如何保证 数据安全 、身份验证、 数据完整性 的:
密码学的一些概念
- 明文: 明文指的是
未被加密
过的原始数据。 - 密文:明文被某种加密算法
加密之后
,会变成密文,从而确保原始数据的安全。密文也可以被解密
,得到原始的明文。 - 密钥:密钥是一种参数,它是在明文转换为密文或将密文转换为明文的算法中输入的参数。密钥分为对称密钥与非对称密钥,分别应用在对称加密和非对称加密上。
- 对称加密:对称加密又叫做
密钥加密
,即信息的发送方和接收方使用同一个密钥去加密和解密数据。对称加密的特点是算法公开、加密和解密速度快,适合于对大数据量进行加密,常见的对称加密算法有DES、3DES、TDEA、Blowfish、RC5和IDEA。 - 其加密解密过程如下:
明文 + 加密算法 + 密钥 => 密文 、 密文 + 解密算法 + 密钥 => 明文
其加密过程中的私钥与解密过程中用到的密钥是同一个
,这也是称加密之所以称之为“对称
”的原因。
-
非对称加密:。非对称加密与对称加密相比,其安全性更好。因为对称加密的通信双方使用相同的密钥,如果一方的密钥遭泄露,那么整个通信就会被破解。而非对称加密使用一对密钥,即公钥和私钥,且二者成对出现。私钥被自己保存,
不能对外泄露
。公钥指的是公开的密钥
,任何人都可以获得该密钥。用公钥或私钥中的任何一个
进行加密,用另一个进行解密。 -
被公钥加密过的密文只能被私钥解密,过程如下:
明文 + 加密算法 + 公钥 => 密文 、 密文 + 解密算法 + 私钥 => 明文
- 被私钥加密过的密文只能被公钥解密,过程如下:
明文 + 加密算法 + 私钥 => 密文 、 密文 + 解密算法 + 公钥 => 明文
由于加密和解密使用了两个不同的密钥,这就是非对称加密“非对称
”的原因,注意两种密钥都可以加密和解密:公钥加密对应私钥解密
,私钥加密对应公钥解密
HTTPS同时采用非对称加密
和对称加密
为什么要采用 非对称加密 和 对称加密 混合加密
只用对称加密方案可行吗?
如果通信双方都各自持有同一个密钥,且没有别人知道,这两方的通信安全当然是可以被保证的(除非密钥被破解)。
然而最大的问题就是这个密钥怎么让传输的双方知晓
,同时不被别人知道。如果由服务器生成一个密钥并传输给浏览器,那在这个传输过程中密钥被别人劫持
到手了怎么办?之后他就能用密钥解开双方传输的任何内容
了,所以这么做当然不行。
换种思路?试想一下,如果浏览器内部就预存了网站A的密钥,且可以确保除了浏览器和网站A,不会有任何外人知道该密钥,那理论上用对称加密是可以的,这样浏览器需要预存好
世界上所有
HTTPS网站的密钥!这么做显然不现实。
怎么办?所以我们就需要非对称加密
只用非对称加密方案可行吗
鉴于非对称加密的机制,我们可能会有这种思路:服务器事先存有公钥和私钥,服务端先把公钥以明文
方式传输给浏览器,之后浏览器向服务器传数据前都先用这个公钥加密
好再传,这样由浏览器向服务器传输数据的安全就可以保障了!因为只有
服务器有相应的私钥
能解开公钥加密的数据。
然而由服务器到浏览器的这条路怎么保障安全?如果服务器用它的私钥加密数据传给浏览器,那么浏览器用公钥可以解密它,而这个公钥是一开始通过明文传输
给浏览器的,若这个公钥被中间人劫持到
了,那他也能用该公钥解密服务器
传来的信息了。所以这样不能保障
由服务器到浏览器的这条路的安全性
改进后的非对称加密方案可行吗
就是浏览器和服务器各有一套
公钥和私钥,这样就可以保证两条路的安全
了
- 某网站服务器拥有公钥A与对应的私钥A’;浏览器拥有公钥B与对应的私钥B’。。
- 浏览器把公钥B明文传输给服务器。
- 服务器把公钥A明文给传输浏览器。
- 之后浏览器向服务器传输的内容都用公钥A加密,服务器收到后用私钥A’解密。由于只有服务器拥有私钥A’,所以能保证这条数据的安全。
- 同理,服务器向浏览器传输的内容都用公钥B加密,浏览器收到后用私钥B’解密。同上也可以保证这条数据的安全
但是为什么不采用这种方案呢?原因是
非对称加密非常耗时
,相比之下对称加密就比较省时快,那么如何利用对称加密的省时
结合非对称加密的安全
呢?
耗时的原因在于:非对称加密中 辨认公钥的真伪 十分麻烦,后面会讲到虽然使用数字证书能保证公钥不被调包,但是同时引发出两个点:1. 如何辨别证书是否被调包;2. 如何辨别证书是否被篡改
非对称加密 + 对称加密 方案的优点
- 快
- 安全
- 某网站拥有用于非对称加密的公钥A、私钥A’。
- 浏览器向网站服务器请求,服务器把公钥A明文给传输浏览器。
- 浏览器随机生成一个用于对称加密的密钥X,用公钥A加密后传给服务器。
- 服务器拿到后用私钥A’解密得到密钥X。
- 这样双方就都拥有密钥X了,且别人无法知道它。之后双方所有数据都通过密钥X加密解密即可
综上所述:为了安全与效率,HTTPS
同时
采用非对称加密
和对称加密
技术:
- 对称加密:利用
客户端
创建的密钥对数据
进行加密,而客户端需要通过发送请求事先告知
服务端秘钥 - 非对称加密:利用证书的公钥和私钥分别对
密钥
进行加解密,以保证秘钥不会被窃取
- 之后的数据传输都是利用密钥对
数据
进行对称加密,然后HTTP负责传输
仍有安全漏洞 —— 中间人调包公钥
- 黑客拦截服务端发来的公钥
- 用
自己伪造的的公钥
并发给客户端 - 客户端无法辨别公钥来源,就用公钥加密秘钥
- 黑客拦截客户端发来的已加密秘钥,通过
自己的私钥
解密获得秘钥(关键步) - 黑客用之前拦截获得的公钥加密秘钥发给服务端
这样在双方都不会发现异常
的情况下,中间人掉包了服务器传来的公钥,进而得到了密钥X。根本原因是浏览器无法确认收到的公钥是不是网站自己的,因为公钥本身是明文传输的
那么如何证明浏览器收到的公钥一定是该网站的公钥?
其实道理就跟如何证明小明出示的身份证一定是小明的,而不是自己伪造的身份证。方法就是看身份证上面印有政府机关公认的印章等等。那么同理,如何给网站颁发一个“身份证”呢?能否有个机构充当互联网世界的“公理”呢?
有,它就是CA机构
,它是如今互联网世界正常运作的前提,而CA机构颁发的“身份证”就是数字证书
。
数字证书
网站在使用HTTPS前,需要向CA机构申领一份
数字证书,数字证书里含有证书持有者信息
、公钥信息
、服务器域名
、权威机构的信息
,还有经过CA私钥签名之后的证书内容,签名计算方法。服务器把证书传输给浏览器,浏览器从证书里获取公钥
就行了,证书就如身份证,证明“该公钥对应该网站
”。但是又有新的问题来了,证书本身的传输过程中,如何防止被篡改呢?
如何防止数字证书被篡改?
我们把证书原本的内容生成一份“签名”,比对证书内容和签名是否一致
就能判别是否被篡改
。这就是数字证书的“防伪技术”,这里的“签名”就叫数字签名
什么是数字签名
图中左侧是数字签名的制作过程,右侧是验证过程
数字签名的制作过程:
- CA机构拥有非对称加密的
私钥
和公钥
。 - CA机构通过hash算法对
证书明文数据T
进行hash
得到散列值
。 - 对散列值
用私钥加密
,得到数字签名S
。明文T
和数字签名S
共同组成了数字证书
,这样一份数字证书就可以颁发给网站了。 那浏览器拿到服务器传来的数字证书后,如何验证它是不是真的?(有没有被篡改、掉包)
浏览器验证过程:
- 拿到证书,得到明文T,签名S。
- 用CA机构的
公钥对S解密
(由于是浏览器信任
的机构,所以浏览器保有
它的公钥。详情见下文),得到S’。 - 用证书里指明的hash算法对明文T进行hash得到T’。 显然通过以上步骤,
- 如果S’
等于
T’,则表明证书可信
; - 如果S’
不等于
T’,则表明该证书有可能被篡改
了,不可信。
为什么这样可以保证证书可信呢?
通过数字签名的方式如何判断出证书被篡改了的?
假设中间人篡改了证书的原文,其对应的散列值就会发生改变,但他由于没有CA机构的私钥
,无法相应地篡改签名S
。浏览器收到该证书后会发现原文和签名解密后的值不一致
,则说明证书已被篡改,证书不可信,从而终止向服务器传输信息,防止信息泄露给中间人。
既然不可能篡改,那整个证书被掉包呢?
中间人有可能把证书掉包吗?
假设有另一个网站B也拿到了CA机构认证的证书,它想劫持网站A的信息。于是它成为中间人拦截到了A传给浏览器的证书,然后替换成自己的证书
,传给浏览器,之后浏览器就会错误地拿到B的证书里的公钥了,这确实会导致上文“中间人攻击”那里提到的漏洞?
其实这并不会发生,因为证书里包含了网站A的信息,包括域名,浏览器把证书里的域名
与自己请求的域名
比对一下就知道有没有被掉包了。
为什么制作数字签名时需要hash一次?
似乎以上过程中hash有点多余,把hash过程去掉也能保证证书没有被篡改。
最显然的是性能问题
,前面我们已经说了非对称加密效率较差,证书信息一般较长,比较耗时。而hash后得到的是固定长度的信息(比如用md5算法hash后可以得到固定的128位的值),这样加解密就快很多。
当然也有安全上的原因,这部分内容相对深一些,感兴趣的自行去了解
怎么证明CA机构的公钥是可信的?
你们可能会发现上文中说到CA机构的公钥,我几乎一笔带过,“浏览器保有它的公钥”,这是个什么保有法?怎么证明这个公钥是否可信?
让我们回想一下数字证书到底是干啥的?没错,为了证明某公钥是可信的,即“该公钥是否对应该网站”,那CA机构的公钥是否也可以用数字证书来证明?没错,操作系统、浏览器本身会预装一些它们信任的根证书
,如果其中会有CA机构的根证书,这样就可以拿到它对应的可信公钥
了。
实际上证书之间的认证也可以不止一层,可以A信任B,B信任C,以此类推,我们把它叫做信任链或数字证书链。也就是一连串的数字证书,由根证书为起点,透过层层信任,使终端实体证书的持有者可以获得转授的信任,以证明身份。
另外,不知你们是否遇到过网站访问不了、提示需安装证书的情况?这里安装的就是根证书。说明浏览器不认给这个网站颁发证书的机构,那么你就得手动下载安装该机构的根证书(风险自己承担)。安装后,你就有了它的公钥,就可以用它验证服务器发来的证书是否可信了。
综上所述:HTTPS 握手具体过程
一、事先对接用于对称加密解密的算法
-
客户端发送自己支持的一些对称加解密算法(一个集合)给服务端
-
服务端从集合里面挑选出一个对称加解密算法,然后发回给客户端,这样客户端和服务端之间就互通了后面对称加密用哪个算法了 二、对接用于非对称加密的证书
-
随后服务端再把
数字证书
传输给客户端,私钥自己留着。(证书内容包括服务器域名、公钥、证书有效期) -
客户端
解析证书
,需要检测的内容有:证书里的域名
与自己请求的域名
比对一下(防止证书被调包),证书明文数据hash之后对应的散列值
与解密得到的数字签名
两者进行对比(防止证书信息被篡改),过期时间
等等,如果发现异常,则会弹出一个警告框,提示证书存在问题。
三、生成秘钥,然后非对称加密传输
- 如果证书没有问题,那么客户端就会生成
密钥
(一串随机数的密码),并用证书中提供的公钥加密
,然后全部发送给服务端 - 服务端收到之后也是先检测证书:对比
证书里的域名
与自己的域名
以及证书明文数据hash之后对应的散列值
与解密得到的数字签名
以防止证书被篡改或调包,然后再用私钥解开获得秘钥
生成随机密钥是为了保证唯一性、随机性(安全)
四、确认双方各自的收发能力
- 客户端通过会话秘钥加密一条消息
发送
给服务端,主要验证服务端是否正常接受
客户端加密的消息。 - 同样服务端也会通过会话秘钥加密一条消息
回传
给客户端,如果客户端能够正常接受
的话表明TLS层连接建立已完成(剩余两次握手)
五、握手完成,传输对称加密数据
- 发送数据:客户端与服务器双方每次发送数据之前,都会对 明文 和之前对接好的 密钥 运用之前对接好的 对称加密算法 进行加密得到 密文
- 接收数据之前,双方都会对收到的 密文 和之前对接好的 密钥 运用之前对接好的 对称解密算法 进行解密得到 明文
每次进行HTTPS请求时都必须在SSL/TLS层进行握手传输密钥吗?
- 服务端会为每个浏览器(统称客户端)各自维护一个
session
,在 SSL 握手过程中,服务端收到客户端发来的密钥后,会把该密钥存到相应的 session 下 - 并生成相应的
session ID
然后发给客户端 - 之后浏览器每次请求都
会携带
session ID - 服务器会根据session ID
找到相应的密钥
并进行解密加密操作,这样就不必每次传输数据都要重新制作、传输密钥了(非对称加密很耗时)
运用与总结
HTTPS 虽然保证了 数据安全、身份验证、数据完整性,但其实也会引发一些问题:
- 成本上:证书费用
- 时间上:HTTPS 握手阶段相比 HTTP 比较耗时,对网站的响应速度有影响,可能会影响用户体验
所以我们采用分而治之的策略:
- 用户浏览的部分用 HTTP 传输
- 涉及用户信息、用户金额方面用 HTTPS 传输
问题回顾
- 为什么不能只用非对称加密?
- 为什么要用对称加密+非对称加密?
- 为什么需要数字证书?
- 为什么需要数字签名?