从HTTP到HTTPS

概述

本文首先会举例介绍http存在的安全隐患,接着从正常思路由浅到深推导如何解决这些安全问题并引出HTTPS的解决方式,然后详细介绍HTTPS的整体过程,最后指出https的局限性。

HTTP简介

http(超文本传输协议)协议是目前应用最为广泛的应用层协议。它的主要功能是基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。目前所有浏览网页的行为都离不开HTTP协议。
HTTP的使用模型也十分简单,如下图所示,客户端机器向服务端发起HTTP请求服务端返回请求指定的资源数据。通俗的讲,使用HTTP协议传输数据就好比,你和你女神上课传纸条。

HTTP传输问题

由于HTTP协议的下层是基于TCP/IP协议的,所以不可避免的,在传输的过程中,数据会经过多个节点进行分组转发。并且HTTP设计初期并没有对传输内容进行加密,因此HTTP协议有以下风险:

  1. 窃听风险:使用明文传递,内容易被窃听;
  2. 不验证通信双方的身份,可能遭遇伪装;
  3. 不能证明报文是否完整,可能已遭篡改。

换句话说,在你和你女神传纸条的时候,你不能直接把纸条递给你女神,必需经过中间好几个同学帮你传一下,在这种情况下,你的情书可能被中间同学看或者篡改,甚至有人可以冒充你女神和你聊天。

解决思路

对称加密

这时有人肯定会说,那把传输内容加个密就好了呗,就好比用个带密码的盒子将你和女神传的纸条锁起来,密码只有你和女神知道,这样传输就安全了。

但其实在互联网的场景下是有问题的,这种以对称加密方式加密时必须将密钥也发给对方。可究竟怎样才能安全地转交?在互联网上转发密钥时,如果通信被监听那么密钥就可会落人攻击者之手,同时也就失去了加密的意义。另外还得设法安全地保管接收到的密钥。

也就是说你和你女神其实是没有机会见面无法以说悄悄话的方式传递密码。你们需要以传纸条的方式交换密码盒的密码。

非对称加密

为了解决对称加密出现的问题,有人提出的非对称加密的方式。非对称加密算法RSA使用一对秘钥,公钥和私钥。公钥用于加密数据,可以公开,私钥用于解密数据,不能公开。在使用RSA加密时即便知道公钥,密文,加密算法解密算法,在不知道私钥的情况下,也无法还原出明文。

还使用上面的例子,女神对想和她聊天的人说,以后咱们使用RSA牌子的电子锁(RSA算法),给我发信息时,使用”520”密码(公钥)对信件进行上锁,通信的第一条信息,你需要告诉我你的密码(公钥),我在回信用这个密码给回信加锁。这样在传纸条的过程中别人无法破译内容了。

起初这一切看起来是那么的美好,但是慢慢的你发现和你女神沟通的效率极低,一般是写信3分钟加密解密5分钟的那种(夸张),女神的回信越来越短,你们的感情越来越淡。

混合加密

为了解决只是用非对称加密带来的计算量大的弊端,我们采用一种混合加密的方式,即使用非对称加密方式传输对称加密的秘钥,在正常的通信中使用对称加密的方式对传输内容进行加密。即除了第一次通信交换秘钥时使用非对称加密外,其他时间使用对称加密,这样既可以保证对称加密秘钥的传输安全又可以保证通信效率。通常来说我们把正常通信前使用非对称加密方式协商对称秘钥的过程叫做握手。

再用传纸条的例子,你第一次和女神聊天时,先从女神那获取到公共的秘钥,然后用公共秘钥以及RSA牌电子锁把密码盒的密码传输给女神,女神确认收到后,之后就使用带密码的密码盒来聊天。

这样感觉是完美的,但是奈何你和女神传纸条时要必经过情敌MITM。这个MITM非常聪明,他可以判断出女神给你发公钥的请求,并将女神的秘钥换成了自己的的公钥发给你。这时MITM有女神的公钥,自己的公私钥,你拿到的是MITM的公钥,并傻呵呵的用他的公钥加密了你给女神的信息传给了MITM。由于有自己的私钥MITM可以看你给女神发的信息,修改后用女神的公钥以你的名义发给女神。这样你和女神都以为直接和对方通信,但其实你们都是和MITM进行通信,MITM不但可以看你给女神发的悄悄话,还可以窜改发送的内容,挑拨你和女神的关系。

这种攻击方式叫做中间人攻击(MITM Man-in-the-middle attack)指攻击者与通讯的两端分别创建独立的联系,并交换其所收到的数据,使通讯的两端认为他们正在通过一个私密的连接与对方直接对话,但事实上整个会话都被攻击者完全控制。

证书体系

中间人能劫持成功的本质,还是因为链路是不安全的。所以没有被加密的握手过程(使用非对称加密方式交换对称加密秘钥的过程)一定会有风险。而目前我们解决问题的思路是建立证书体系。简单来说,一个HTTPS网站响应给我们的并不是一个公钥,而是证书,证书是由权威机构发布,上不但包含了公钥,还包含了域名、签发机构、有效期、签名等等信息,我们可以通过简单的方式验证其真实有效性,只要验证通过我们就可以相信证书中的内容,获得并使用证书中的秘钥。

问题目前从如何确保服务端提供的公钥没有被中间人篡改过,变为了如何确保服务端提供的证书没有被中间人篡改过。这就要提到数字签名技术了。证书是由权威机构颁发给服务端的,证书中要包括明文的主体信息内容以及数字签名,主体信息内容主要包括服务方公钥,服务方域名,有效期,签发机构等,数字签名是在证书末尾增加用于验证内容是否被篡改的密码。签名的生成方式是对证书主体内容使用消息摘要算法,生成固定长度的摘要字符串,然后用权威机构的私钥对摘要字符串进行加密。证书生成如下图所示。当客户端拿到证书后,使用内嵌在浏览器或操作系统中权威机构的公钥对数字签名进行解密,得到权威机构确认的证书的摘要信息A,然后再用相同的摘要算法(在证书明文部分会指明)计算出证书摘要信息B,如果摘要信息A与摘要信息B相同,就说明这个证书是权威机构颁发(使用机构公钥可解密签名)且证书内容没有被篡改(服务端算的摘要字符串和权威机构算的摘要字符串相等)。
证书生成过程

在上述过程中我们必须默认权威机构提供的证书内容是真是可信的,至于如何保证其可信性是权威机构需要考虑的问题,在此不过多讨论。再用传纸条的例子举例,我们之前的问题落在如何验证女神给你的公钥就是女神的公钥,而不是被MITM篡改后其他人的公钥。现在的方法是女神不直接给她的公钥了,而是给班长签发给女神的一个证书,这个证书包含了女神公钥,并且班长在下面签了个名,写到”这个证书总共有X个中文X个英文X个标点,我作证这个证书确实是女神的,张XX”,由于班长的字很难模仿,所以你一看就确认是班长写的,然后你一数证书内容和班长写的一样你就可以确认没被修改过。然后你就可以放心大胆使用证书中的公钥了。

小结

至此形成了一套安全传纸条的流程,这个流程基本就是HTTPS传输的基本思路了。简单的说,就是在HTTP下层增加传输层安全协议(SSL/TLS),该层负责建立安全通路。安全通路使用对称加密方式对传输内容进行加密,对称加密秘钥使用非对称加密方式加密传输,不直接交换非对称加密中的公钥,而是使用证书替代,保证公钥在传输中不能被篡改。之后一个小节将会阐述HTTPS建立安全通路的流程。

HTTPS流程

HTTPS流程

HTTPS的基本流程框架如上图,总结来说分为以下几步:

  1. Client发起一个HTTPS(https:/demo.linianhui.dev)的请求,根据RFC2818的规定,Client知道需要连接Server的443(默认)端口。
  2. Server把事先配置好的公钥证书(public key certificate)返回给客户端。
  3. Client验证公钥证书:比如是否在有效期内,证书的用途是不是匹配Client请求的站点,是不是在CRL吊销列表里面,它的上一级证书是否有效,这是一个递归的过程,直到验证到根证书(操作系统内置的Root证书或者Client内置的Root证书)。如果验证通过则继续,不通过则显示警告信息。
  4. Client使用伪随机数生成器生成加密所使用的会话密钥,然后用证书的公钥加密这个会话密钥,发给Server。
  5. Server使用自己的私钥(private key)解密这个消息,得到会话密钥。至此,Client和Server双方都持有了相同的会话密钥。
  6. Server使用会话密钥加密“明文内容A”,发送给Client。
  7. Client使用会话密钥解密响应的密文,得到“明文内容A”。
  8. Client再次发起HTTPS的请求,使用会话密钥加密请求的“明文内容B”,然后Server使用会话密钥解密密文,得到“明文内容B”。

以上只是一个抽象的HTTPS的一个工作流程,实际上SSL/TLS所做的工作远不止这这些,更详细的解释请参考这篇文章

HTTPS的局限性

上面我们讨论的都是客户端在服务端通信的过程中,如何保证交互的内容不被修改。目前HTTPS已经给出了一个较为完善的机制。在http协议被广泛应用的今天,有些APP甚至手机游戏也会选择用http协议作为传输协议,但其实这是有极高的安全风险的。因为HTTPS主要保证的就是客户端与服务端传输的数据没有被第三方篡改,但是如果客户端和第三方想欺骗服务端,还是可以做到的。做法还是使用MITM攻击,通过在设备中设置不受信的证书验证机构,人为设置HTTP代理,引入中间人,使HTTP传输的内容不是客户端发出的,而是中间人修改过的,从而达到欺骗服务端的目的。比如一个游戏使用https作为传输协议,有一关你始终打不过去(战斗计算发生在客户端),这时可以使用中间人修改游戏APP向服务器发送的战斗结果信息,将你始终置为获胜方。