HTTPs 小故事
HTTP 和 HTTPS 是互联网的基石,正是有了它们的存在才可以使互联网如此的开放而繁荣。我大学是学的网络工程,这些都是专业知识,只是毕业多年也都忘得差不多了,最近在研究代理相关的技术,HTTPS 也是绕不开的内容,这里做个笔记。
HTTPS
HTTP 可以进行网络通信,既然有了 HTTP 又为什么需要 HTTPS 呢?
HTTPS 的全称是 Hypertext Transfer Protocol over Secure Socket Layer,是以安全为目标的HTTP通道。通俗来讲 HTTPS 并不是一个新的协议,而是在原来的 HTTP 协议上进行了数据加密,HTTP 为什么需要加密呢?可以看下面的几个小故事来方便理解。
明文通信
假定客户端叫做夏洛,服务器叫做马冬梅,夏洛和马冬梅距离非常远,需要通过邮件来通信。
如果夏洛想要约马冬梅周六去看海,他就会写一封信,信里约定了时间地点,把信装到信封里给邮差,然后邮差把信送给马冬梅,马冬梅收到了信写一封回信给夏洛答应周末去看海,到了周末他们就在约定的地点碰头,非常完美。
但这个邮差不是普通的邮差,这个邮差叫袁华,他也偷偷喜欢马冬梅,每个经过他送给马冬梅的信他都会拆开看一下。看到这封约会的信他害怕马冬梅会答应,于是他偷偷改了信里的约会地点,把去看海改成了去爬山。然后马冬梅的回信被他改成了拒绝。这样到了周六,夏洛因为被拒绝了没有去,而马冬梅去山脚下等了一天没有等到人,最后非常的生气。
这就是 HTTP 的工作流程,整个传输过程都是明文传输,任何经手的人都可以任意篡改网站的内容。
对称加密
假如马冬梅非常生气,直接去找了夏洛,俩人一沟通,就会发现有人篡改了信的内容。但是除了通过邮差通信没有其他办法远距离沟通,那怎么办呢?
夏洛非常机智,他说可以使用带锁的盒子来放信件,两人各一个盒子和一把钥匙,写好的信放到盒子里锁住再给邮差,对方拿到盒子后用钥匙打开盒子才能看到信。这样邮差没有钥匙,就无法看到信和里面的内容了。
上面这种方法就是对称加密
,对称加密是使用同一个秘钥进行加密和解密。如果除了发信人和收信人外没有人知道秘钥,那么通信就是安全的。例如将一段文本中的每个字母按照字母表中的顺序前移三位。比如,D→A,E→B,F→C。如此一来,原文为 secret message
的信息就变成了 pbzobq jbppxdb
,没有密码没法理解其中的内容,而如果随意篡改了内容,则解密后的内容是乱码无法阅读,也会知道内容被篡改了。
夏洛和马冬梅直接的通信问题解决了,后面他们结婚,住到了一起,开了一家乡村银行。由于地广人稀,存钱取钱还是要通过邮差,但是经常会发现数目不对的情况,赔了不少钱。
于是夏洛使用对称加密的方法,他造出来了很多盒子,每个盒子都有两把钥匙,如果一个叫大春的人想要存钱,就按照如下步骤进行:
大春找到夏洛,说想要在他的银行存款;
夏洛给了大春一个盒子和配套的一把钥匙,另一把钥匙自己保管;
如果大春在外地想要取钱的话就把取多少钱的信放到盒子里并锁着,通过邮差寄给夏洛;
夏洛收到盒子用钥匙打开,读了信后,把响应的钱放进盒子里并锁住,过邮差寄会给大春;
大春收到盒子用钥匙打开,拿到了钱;
非对称加密
上面的方式发现了一个问题。这种通信方式需要大春先去夏洛那里拿到盒子和钥匙,而如果不方便到夏洛那里去就没办法拿到盒子和钥匙。如果通过邮差来传递的话,那么邮差就可以给大春假的盒子和钥匙,从而在邮寄途中偷偷把钱拿走。
经过冥思苦想,夏洛想出来一个更好的方式。于是大春存取款都按照新的步骤进行:
大春先经过邮差寄给夏洛发一个要存钱的信;
夏洛把一个盒子(没有钥匙,锁开着)通过邮差寄给大春;
大春把钱放到盒子里,然后用锁锁住寄给夏洛;
夏洛收到盒子后用钥匙打开盒子,把钱拿出来放到金库里;
这样夏洛只需要一个盒子和一把钥匙就可以了,钥匙自己保管不需要给大春,邮差没有钥匙也打不开盒子没法拿到盒子里的钱。
这就是非对称加密。非对称加密是一种使用不同秘钥进行加密和解密的加密算法,非对称加密有两个秘钥——公开秘钥和私有秘钥(下文简称公钥和私钥),公钥用来加密,私钥用来解密,以公钥加密的内容只能使用私钥解密。这样的话,私钥只会让自己知道,公钥的话可以让任何人知道,保证了安全。
认证加密
刚开始运行良好,没有什么问题,好景不长,过了一段时间又发现数目不对的情况了。经过调查发现邮局有人仿造了夏洛的盒子。在夏洛把盒子给大春的过程中,截留了夏洛的盒子,把仿造的盒子给了大春,然后拿到大春寄回来的盒子后,用仿造盒子的钥匙把盒子打开,把钱截留了一部分,把剩下的钱放到真正的盒子里给夏洛。这样两边都没法发现钱少了,只有最后取钱发现钱不够了时才会出现问题。
夏洛没有办法,求助警局,警局给夏洛的盒子加了个无法仿造的警徽标记,只要拿着盒子到当地的警局就能确认这个盒子是不是真的,这样邮局就没办法自己仿造盒子了,从而保障了整个交易过程。
这里警局在术语中就被成为 签证机构 Catificate Authority
,简称 CA
。盒子就是公钥,钥匙就是私钥。关于 CA
相关的内容后面再单独写一篇文章来讲。
HTTPS 认证过程
下面来说一下实际 HTTPS 的认证过程(TLS 1.3)[3][4][5][6][7][8]:
TCP 三次握手建立会话,这里就不进行解释了。
客户端发送Client Hello,给出以下内容:
- TLS协议版本信息(Client Version);
- 客户端生成的随机数(Client Random);
- 客户端支持的加密算法列表(Cipher Suites);
- 客户端支持的压缩算法列表(Compression Methods);
- 其他扩展字段(Extensions)[6]。
服务器收到客户端的Client Hello后,发送Server Hello,确认协商的信息结果:
- 确定协商使用的TLS版本号
TLS 1.0
/TLS 1.1
/TLS 1.2
/TLS 1.3
(Server Version); - 服务器生成的随机数(Server Random);
- 服务器选择的最终的加密算法(Cipher Suite);
- 服务器选择的最终的压缩算法(Compression Method);
- 其他扩展字段(Extensions)[6]。
- 确定协商使用的TLS版本号
服务器给出终端数字证书(证书中包含Host、公钥和CA签名)。
服务器发送Server Key Exchange,对于使用DHE/ECDHE非对称密钥协商算法的SSL握手,将发送该类型握手。RSA算法不会进行该握手流程(DH、ECDH也不会发送server key exchange),也就是说此报文不一定要发送,视加密算法而定[9]。
服务器发送Server Hello Done,通知客户端 Server Hello 信息发送结束。
客户端通过CA验证数字证书签名的合法性后,生成一个新的随机数,并使用服务器给出的终端数字证书中的公钥,加密这个随机数,发给服务器。
服务器使用自己的私钥,获取客户端发来的随机数(即Premaster secret)。
服务器和客户端根据约定的加密方法,使用前面的三个随机数,协商生成"对话密钥"(Session Key)。
服务器发送New Session Ticket,用处就是在一段时间之内(超时时间到来之前),双方都以协商的密钥进行通信。
接下来用"对话密钥"(Session Key)来进行对称加密传输会话内容。
完成数据发送,TCP 4次挥手结束会话。