你了解HTTPS 的加解密原理吗

本篇将讨论 HTTPS 的加解密原理,很多人都知道 RSA,以为 HTTPS=RSA,使用 RSA 加解密数据,实际上这是不对的 。
HTTPS 是使用 RSA 进行身份验证和交换密钥,然后再使用交换的密钥进行加解密数据 。
身份验证是使用 RSA 的非对称加密,而数据传输是双方使用相同的密钥进行的对称加密 。那么,什么是对称加密和非对称加密?

我自己是一名从事了多年开发的web前端老程序员,目前辞职在做自己的web前端私人定制课程,今年年初我花了一个月整理了一份最适合2019年学习的web前端学习干货,各种框架都有整理,送给每一位前端小伙伴,想要获取的可以关注我的头条号并在后台私信我:前端,即可免费获取 。
对称加密和非对称加密
假设隔壁小王想要约小红出来,但是他不想让小明知道,于是他想用对称加密给小红传了个小纸条 。
如下图所示:
你了解HTTPS 的加解密原理吗

文章插图
 
他想发送的数据是"Meet at 5:00 PM"(5 点见面,如果是中文的话可以使用 UTF-8 编码),加密方式是直接在 ASCII 表进行左移或右移 。
【你了解HTTPS 的加解密原理吗】他的密钥是 3,表示在 ASCII 表往后移 3 位,就会变成"Phhw#dw#8=33#SP",这样一般人如果截获了不知道是什么意思的 。
但是我们可以想一下,如果既然他可以截获你的数据,自然也可以截获你的密钥,进而进行解密 。
如下图所示:
 
你了解HTTPS 的加解密原理吗

文章插图
 
 
所以小王打算用非对称加密,非对称加密的特点是双方都有自己的公钥和私钥对,其中公钥发给对方,密钥不交换自己保管不泄漏 。
如下图所示:
你了解HTTPS 的加解密原理吗

文章插图
 
其中小红的公钥为:
public_key = (N, e) = (3233, 17)她把公钥发给了小明,她自己的私钥为:
private_key = (N, e) = (3233, 2753) 
这里注意公钥和私钥都是两个数,N 通常是一个大整数,e 表示一个幂指数 。现在小王想给小红发消息,于是他用小红的公钥进行加密,怎么加密呢?
 
他要发送的第一个字母为 t=“M”,“M”的 ASCII 编码为 77,77 的加密过程如下计算:
T = 77 ^ e % N = 77 ^ 17 % 3233 = 3123 
把 77 做 e 次幂然后模以 N,便得到了 T=3123,然后把这个数发给小红(其他字母按同样方式处理) 。
小红收到 T 之后便用她的私钥进行解密,计算如下:
t = T ^ e % N = 3123 ^ 2753 % 3233 = 77 
计算方法是一样的,这样便把 T 还原成了 t,只要公私钥配对,便可通过一些数学公式证明上面的推算是成立的 。这个就是 RSA 的加解密原理,如果无法知道私钥便无法进行正确解密 。
 
反过来,使用私钥进行加密,公钥进行解密也是可行的 。那么 HTTPS 是怎么利用 RSA 进行加解密的呢,我们从 HTTPS 连接建立过程说起 。
HTTPS 连接建立过程
HTTPS 主要有以下作用:
  • 验证服务方身份,如我访问 google.com 的时候连的确实就是谷歌服务器
  • 防止数据被劫持,例如有些运营商会给 http 的页面插入广告
  • 防止敏感数据被窃取篡改等
 
正如 openssl 的注释所说,这是防止中间人攻击的唯一方法:
你了解HTTPS 的加解密原理吗

文章插图
 
我们以 MDN(https://developer.mozilla.org)的网站为例,然后用 wireshark 抓包,观察 HTTPS 连接建立的过程 。
 
如下图所示:
你了解HTTPS 的加解密原理吗

文章插图
 
首先是 TCP 三次握手,然后客户端(浏览器)发起一个 HTTPS 连接建立请求,客户端先发一个 Client Hello 的包,然后服务端响应一个 Server Hello 。
 
接着再给客户端发送它的证书,然后双方经过密钥交换,最后使用交换的密钥加行加解密数据 。
 
在 Client Hello 里面客户端会告知服务端自己当前的一些信息,如下图所示:
 
你了解HTTPS 的加解密原理吗

文章插图
 
 
包括客户端要使用的 TLS 版本,支持的加密套装,要访问的域名,给服务端生成的一个随机数(Nonce)等 。
 
需要提前告知服务器想要访问的域名以便服务器发送相应的域名的证书过来,因为此时还没有发生 HTTP 请求 。


推荐阅读