HTTPS
总览
HTTPS和HTTP、对称加密和非对称加密、中间人攻击、摘要算法和数字签名算法、数字证书、SSL/TLS与HTTPS链接的建立
# HTTP和HTTPS
HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全,存在信息被窃听、篡改的风险,为了保证这些隐私数据能加密传输,从而就诞生了HTTPS。简单来说,HTTPS 就是在 HTTP 与 TCP 层之间增加了 SSL/TLS 安全传输层,HTTP的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比HTTP协议安全。
HTTP 连接建立相对简单, TCP 三次握手之后便可进行 HTTP 的报文传输。而 HTTPS 在 TCP 三次握手之后,还需进行 SSL/TLS 的握手过程,才可进入加密报文传输。
# HTTPS特征
信息加密:交互信息无法被窃取
混合加密的方式实现信息的机密性,解决了窃听的风险。
校验机制:无法篡改通信内容,篡改了就不能正常显示
摘要算法的方式来实现完整性,它能够为数据生成独一无二的「指纹」,指纹用于校验数据的完整性,解决了篡改的风险。
身份证书:CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的
将服务器公钥放入到数字证书中,解决了冒充的风险。
它采用的就是上面说的 “混合加密” + “数字证书” 两种技术,来保证整个通信过程的安全可靠。
# 对称加密
对称密钥加密的特点就是使用相同的密钥进行加密和解密
![image-20230324143409392](/assets/img/image-20230324143409392.2ddcb6ac.png)
常见的对称加密算法:
DES: 将64bit明文加密成64bit密文的对称加密算法
密钥过短容易被暴力破解
3DES:将DES重复三次 加密+解密+加密(每次密钥不同)
三次DES时间过长,速度慢
AES:新标准的对称加密算法
AES是一种分组加密算法,在对明文加密的时候,并不是把整个明文一股脑加密成一整段密文,而是把明文拆分成一个个独立的明文块,每一个明文块长度128bit。这些明文块经过AES加密器的复杂处理,生成一个个独立的密文块,这些密文块拼接在一起,就是最终的AES加密结果。
密钥配送问题 即如何防止公钥在传输的过程中被窃听
- 事先共享密钥
- 密钥分配中心(KDC)
- 非对称加密
# 非对称加密
通信的双方使用不同的秘钥进行加密解密,即秘钥对(私钥 + 公钥)。
公钥和私钥是一一对应的,不能单独生成
![image-20230324145606381](/assets/img/image-20230324145606381.c454cef3.png)
![image-20230324143928696](/assets/img/image-20230324143928696.3c9da3fc.png)
- 接收方 B 创建一个公钥和一个私钥,公钥被发送给 A
- A 使用从 B收到的公钥加密数据,将密文发送给 B
- B使用私钥解密从 A接收到的密文,得到原始数据
非对称加密算法:RSA
# 混合加密(非对称加密+对称加密)
HTTPS 采用的是对称加密和非对称加密结合的「混合加密」方式:
会话密钥:为本次通信随机生成的临时密钥作为对称加密的密钥,用于加密消息,提高速度
- 在通信建立前采用非对称加密的方式交换「会话秘钥」,后续就不再使用非对称加密。
- 在通信过程中全部使用对称加密的「会话秘钥」的方式加密明文数据。
采用「混合加密」的方式的原因:
- 对称加密只使用一个密钥,运算速度快,密钥必须保密,无法做到安全的密钥交换。
- 非对称加密使用两个密钥:公钥和私钥,公钥可以任意分发而私钥保密,解决了密钥交换问题但速度慢。
加密过程
- 消息接收者生成一对公钥和私钥
- 消息发送者拿到消息接收者的公钥
- 随机生成会话密钥,用会话密钥加密消息(非对称加密)
- 用接收者的公钥加密会话密钥(对称加密)
- 将2和3一并发给消息接收者
解密过程
- 消息接收者用自己的私钥解密出会话密钥
- 在用解密出的会话密钥,解密消息
一图流
# 数字签名与摘要算法
- 生成签名
由消息发送者完成。通过签名密钥生成
- 验证签名
由消息接收者完成,通过验证密钥验证
一般我们不会用非对称加密来加密实际的传输内容,因为非对称加密的计算比较耗费性能的。
过程改进,用摘要算法**(哈希函数)来计算出内容的哈希值**,这个哈希值是唯一的,且无法通过哈希值推导出内容
所以非对称加密的用途主要在于通过「私钥加密,公钥解密」的方式,来确认消息的身份,我们常说的数字签名算法,就是用的是这种方式,不过私钥加密内容不是内容本身,而是对内容的哈希值加密。
用公钥加密内容,然后用私钥解密,也可以用私钥加密内容,公钥解密内容。流程的不同,意味着目的也不相同:
- 公钥加密,私钥解密。这个目的是为了保证内容传输的安全,因为被公钥加密的内容,其他人是无法解密的,只有持有私钥的人,才能解密出实际的内容;
- 私钥加密,公钥解密。这个目的是为了保证消息不会被冒充,因为私钥是不可泄露的,如果公钥能正常解密出私钥加密的内容,就能证明这个消息是来源于持有私钥身份的人发送的。
# 中间人攻击
如果遭到中间人攻击,那公钥可能是伪造的
中间人截取了对方发给我们的公钥,然后将他自己的公钥发送给我们,当我们使用他的公钥加密后发送的信息,就可以被他用自己的私钥解密。然后他伪装成我们以同样的方法向对方发送信息,这样我们的信息就被窃取了,然而自己还不知道。为了解决这样的问题,可以使用数字证书。
A
拿到的其实是 X
发送给他的伪造公钥,但是 A
无法察觉
最后,X
用他自己的密钥加密响应数据,并发送给 A
,就这样,虽然 A
、B
双方能顺利完成通信,但是恶意的第三方 X
能看到解密后的请求数据和响应数据,而 A
、B
双方则毫不知情。
这种通过秘密替换公钥窃取数据的方法被称为“中间人攻击”,问题的根源在于 A
无法确认他们收到的公钥是否由 B
方创建
# 数字证书
如何解决中间人攻击?
出现了权威的机构就是 CA (数字证书认证机构),将服务器公钥放在数字证书(由数字证书认证机构颁发)中,只要证书是可信的,公钥就是可信的,通过数字证书的方式保证服务器公钥的身份,解决冒充的风险。
事实上,认证机构形成一个树形结构,高级别的权威机构为较低级别的机构创建证书,那就是说,如果要验证的话,就是一级一级向上认证,信任链条的最终是Root CA,他采用自签名,对他的签名是无条件的信任。
# SSL/TLS与HTTPS链接的建立
HTTPS 做的事情其实就是在传输层跟应用层之间加了一层 SSL/TLS
,用于对 TCP 传输内容的加密和解密
SSL 是 “Secure Sockets Layer” 的缩写,中文叫做「安全套接层」。它是在上世纪 90 年代中期,由网景公司设计的。
到了1999年,SSL 因为应用广泛,已经成为互联网上的事实标准。IETF 就在那年把 SSL 标准化。标准化之后的名称改为 TLS(是 “Transport Layer Security” 的缩写),中文叫做 「传输层安全协议」。一般把这两者并列称呼(SSL/TLS),因为这两者可以视作同一个东西的不同阶段。
TLS/SSL的功能实现主要依赖三类基本算法:散列函数hash、对称加密、非对称加密。这三类算法的作用如下:
- 散列算法用来验证信息的完整性
- 对称加密算法采用协商的秘钥对数据加密
- 非对称加密实现身份认证和秘钥协商
SSL/TLS 协议基本流程:
- 客户端向服务器索要并验证服务器的公钥。
- 双方协商生产「会话秘钥」。
- 双方采用「会话秘钥」进行加密通信。
前两步也就是 SSL/TLS 的建立过程,涉及四次通信,使用不同的密钥交换算法,TLS 握手流程也会不一样的,现在常用的密钥交换算法有两种:RSA 算法和 ECDHE 算法
# TLS 协议建立的详细流程
![](/assets/img/23.937e4dac.png)
1.ClientHello
客户端向服务器发送"Client Hello"消息,该消息中包含了客户端支持的SSL/TLS的版本,支持的加密套件列表(例如RSA加密,AES加密等),以及一个客户端生成的随机数
2.SeverHello
服务器回应"Server Hello"消息,该消息中包含了服务器选择使用的SSL/TLS的版本,选择的加密套件,以及一个服务器生成的随机数。
3.Certificate
服务器发送"Certificate"消息,该消息包含了服务器的证书信息。证书里包含了服务器的公钥和由证书颁布机构(CA)签名的数字签名
4.
客户端会验证服务器的证书,客户端生成一个新的随机数,然后用服务器的公钥加密这个随机数,然后发送给服务器。这个随机数会被用来生成对话密钥,对话密钥会用于接下来的数据加密。
5.
服务器用自己的私钥解密这个消息,得到客户端发送的随机数。然后,服务器和客户端根据之前交换的所有随机数生成对话密钥。
6.
服务器和客户端互相通知对方开始使用新的对话密钥加密接下来的信息
# 客户端校验数字证书的流程
CA 签发证书的过程,如上图左边部分:
- 首先 CA 会把持有者的公钥、用途、颁发者、有效时间等信息打成一个包,然后对这些信息进行 Hash 计算,得到一个 Hash 值;
- 然后 CA 会使用自己的私钥将该 Hash 值加密,生成 Certificate Signature,也就是 CA 对证书做了签名;
- 最后将 Certificate Signature 添加在文件证书上,形成数字证书;
客户端校验服务端的数字证书的过程,如上图右边部分:
- 首先客户端会使用同样的 Hash 算法获取该证书的 Hash 值 H1;
- 通常浏览器和操作系统中集成了 CA 的公钥信息,浏览器收到证书后可以使用 CA 的公钥解密 Certificate Signature 内容,得到一个 Hash 值 H2 ;
- 最后比较 H1 和 H2,如果值相同,则为可信赖的证书,否则则认为证书不可信。
对于这种三级层级关系的证书的验证过程如下:
- 客户端收到 baidu.com 的证书后,发现这个证书的签发者不是根证书,就无法根据本地已有的根证书中的公钥去验证 baidu.com 证书是否可信。于是,客户端根据 baidu.com 证书中的签发者,找到该证书的颁发机构是 “GlobalSign Organization Validation CA - SHA256 - G2”,然后向 CA 请求该中间证书。
- 请求到证书后发现 “GlobalSign Organization Validation CA - SHA256 - G2” 证书是由 “GlobalSign Root CA” 签发的,由于 “GlobalSign Root CA” 没有再上级签发机构,说明它是根证书,也就是自签证书。应用软件会检查此证书有否已预载于根证书清单上,如果有,则可以利用根证书中的公钥去验证 “GlobalSign Organization Validation CA - SHA256 - G2” 证书,如果发现验证通过,就认为该中间证书是可信的。
- “GlobalSign Organization Validation CA - SHA256 - G2” 证书被信任后,可以使用 “GlobalSign Organization Validation CA - SHA256 - G2” 证书中的公钥去验证 baidu.com 证书的可信性,如果验证通过,就可以信任 baidu.com 证书。
在这四个步骤中,最开始客户端只信任根证书 GlobalSign Root CA 证书的,然后 “GlobalSign Root CA” 证书信任 “GlobalSign Organization Validation CA - SHA256 - G2” 证书,而 “GlobalSign Organization Validation CA - SHA256 - G2” 证书又信任 baidu.com 证书,于是客户端也信任 baidu.com 证书。
总括来说,由于用户信任 GlobalSign,所以由 GlobalSign 所担保的 baidu.com 可以被信任,另外由于用户信任操作系统或浏览器的软件商,所以由软件商预载了根证书的 GlobalSign 都可被信任。
但事实上,证书的验证过程中还存在一个证书信任链的问题,因为我们向 CA 申请的证书一般不是根证书签发的,而是由中间证书签发的
# 简单总结
# 参考
HTTP 协议入门 - 阮一峰的网络日志 (ruanyifeng.com) (opens new window)
图解HTTP
小林coding