十分钟了解HTTPS
一、为什么要用HTTPS——HTTP协议的缺陷
-
通信使用明文(不加密),内容可能会被窃听
-
不能验证通信方的身份,所以请求和响应都有可能是攻击者发送的
数据包在由A到B的过程中,可能经历很多次路由转发,这个过程中数据包可能会被劫持和替换,A和B都无法确定收到的信息是否就是对方发送的。
-
无法证明报文的完整性,可能是经过篡改的信息。
同样是在A到B传输过程中,数据包被劫持、篡改之后继续传输,虽然接收方收到的数据包就是发送方发送的那个,但是内容已经遭到篡改,这样无法保证报文的完整性。
二、HTTPS是怎么克服这些缺陷的?
2.1 HTTPS是什么?
HTTPS: 在HTTP通信时增加一层TLS通信,以前是HTTP直接和TCP通信,现在HTTP先与TLS通信,再由TLS和TCP进行通信。HTTPS拥有加密、证书校验身份、准确性校验这些功能,避免了HTTP的三个缺陷。
TLS的前身是SSL,TLS 1.0通常被标示为SSL 3.1,TLS 1.1为SSL 3.2,TLS 1.2为SSL 3.3。
HTTP建立通信时,只需要进行TCP三次握手就可以开始传输数据了,而HTTPS在建立通信时,先进行TCP三次握手,再进行TLS握手,然后开始发送数据。
2.2 HTTPS的加密功能
加密技术分为:
-
共享密钥加密,也叫对称密钥加密,只有一把密钥,通信方必须先将密钥发送给接收方,然后接收方使用密钥对密文解密,但是密钥发送的过程很难保证安全,一旦密钥被窃取,就不能保证加密的安全了。
-
公开密钥加密,即非对称密钥加密,有两把密钥,公钥public key 和私钥private key
公钥是公开的,可以随意发布,任何人都可以获得。A使用B发布的公钥加密报文,B接收后使用自己的私钥进行解密,这样私钥不需要传输,也就不必担心被窃取的风险。
对称加密处理速度要比非对称加密要快,所以在保证安全的基础上,应多使用对称加密方式。TLS采用非对称加密的加密方式,HTTPS采用混合加密机制: 大部分通信使用对称密钥加密,但首次交换共享密钥时是使用非对称加密的方式,这样就既保证了安全,又速度最快。
2.3 HTTPS的身份认证功能
按照上文介绍的非对称加密方式,会有一个安全缺陷:客户端怎么知道拿到的公钥是否就是服务端发放的公钥呢,因为在拿到的过程中,公钥有可能被掉包。于是为了避免这个缺陷,引入了证书的概念。
公钥证书
为了保证公钥是目标服务器发行的公钥,需要使用权威第三方机构(以下称为CA机构)颁发的公钥证书:
- 服务器去CA机构申请证书,机构颁发加数字签名的公钥证书,数字签名可以使用CA机构的公钥来验证;
- 服务器把公钥证书以公开密钥加密方式传给客户端;
- 浏览器内会植入常用CA机构的公钥;
- 客户端从浏览器拿到CA机构的公钥,并用它验证收到的公钥证书的数字签名,验证通过,证明服务器的公钥值得信任,客户端就从公钥证书取出公钥。
总结一下就是服务器传递的公钥上有CA的签名,客户端通过验证签名证实服务器的身份,并安全地得到公钥。
HTTPS首次交换共享密钥使用的是非对称加密方式,这种加密方式会使用公钥证书来验证服务端的身份。而想要验证客户端的身份就不是那么容易了,需要用户去申请证书,而且权威机构的证书是要花钱的,所以客户端身份验证充满挑战。现状是,仅有特殊用途的业务实现了客户端证书,比如那些可支撑客户端证书支出费用的业务,例如银行网银就采用了客户端证书。
2.4 HTTPS的完整性校验功能
在HTTPS的通信流程中,应用层发送数据时,会附加一种叫做MAC的报文摘要,MAC能够查知报文是否遭到篡改,从而保护报文的完整性。
三、HTTPS建立通信的过程简介
HTTPS首次建立通信时,假设C是客户端client,S是服务器端server,以SSL为例:
-
C/S会先进行TCP三次握手;
-
然后C发送Client Hello报文及其他SSL信息,表示开始SSL通信过程;
-
S收到后回以Server Hello及其他SSL信息,此外S还发送公钥证书,随后发送Server Hello Done通知Client SSL握手协商部分结束
即SSL第一次握手结束,这个过程最重要的是S把公钥证书交给了C;
-
C验证公钥证书有效性,然后取出公钥,然后:
- 回以Client Key Exchange报文,报文中包含通过公钥加密过的Pre-master-secret是一个随机密码串。
- C接着发送Change Cipher Spec报文,告诉S此报文后的通信会用Pre-master-secret进行加密。
- C发送Finished报文,并包含上述全部报文的整体校验值。这次握手协商能否成功,要看S是否正确解密该报文。
-
S收到加密过的pre-master secret,用自己的私钥得到pre-master secret,然后:
-
发送Change Cipher Spec报文
-
S发送Finished报文。
-
-
C/S使用pre-master secret+客户端随机数+服务端随机数经过一系列算法,生成master secret 主密钥,使用master secret生成对称密钥session key,之后传输的收据均使用session key加密解密。
至此,SSL连接建立完成,这个过程最重要的是C把Pre-master-secret用上一步传递的公钥加密后传给S。之后开始进行HTTP通信,并用共享密钥对通信进行对称加密。
四、HTTPS的问题
当使用SSL时,它的处理速度变慢:
- 通信速度变慢,因为除了HTTP请求和响应,还要进行SSL通信,通信量会增加
- 因为C/S端都要加密解密,更耗计算资源,SSL加速器可以改善S端问题
建议的是如果非敏感信息使用HTTP通信,只有在包含个人信息等敏感数据时,才利用HTTPS进行通信。特别是访问量较多的网站在加密处理时,会承担较大的负载,可以仅在需要信息隐藏时才加密,以节约资源。但是查看淘宝、京东都是所有请求都采用的HTTPS,也有搜索到一些讲部分页面采用HTTP,部分页面采用HTTPS的部署方法的博文,因为现在我对部署这一块的东西还比较生疏,所以后续有时间再关注。
默认端口
- HTTP默认端口80
- HTTPS默认端口443
下面我们来聊一聊HTTPS
如何做到防劫持。
SSL握手
先来看看HTTPS
建立连接的过程,相比HTTP
的三次握手,HTTPS
在三次握手之后多了SSL
握手。如下图:
整个流程大概如下:
1.浏览器将自己支持的一套加密规则发送给网站。
2.网站部署了一组SSL秘钥,分私钥和秘钥。
3.网站从浏览器的加密规则中选出一组加密算法与HASH算法,并将自己的身份信息(公钥)以证书的形式发回给浏览器。证书里面包含了网站地址,加密公钥,以及证书的颁发机构等信息。
4.获得网站证书之后浏览器要做以下工作:
a) 验证证书的合法性(颁发证书的机构是否合法,证书中包含的网站地址是否与正在访问的地址一致等),如果证书受信任,则浏览器栏里面会显示一个小锁头,否则会给出证书不受信的提示。
b) 如果证书受信任,或者是用户接受了不受信的证书,浏览器会生成一串随机数的密码,并用证书中提供的公钥加密。
c) 使用约定好的HASH计算握手消息,并使用生成的随机数对消息进行加密。这个加密过程是非对称加密,即公钥加密,私钥解密。私钥只在网站服务器上存储,其他人无法获得这个私钥,也就无法解密。可理解为公钥是锁,私钥是钥匙,客户端将随机数用公钥锁上,经过网络传输到服务器,整个过程就算有人拦截了信息,由于没有私钥解锁,也就无法解密。
过程如下图:
5.将生成的所有信息发送给网站。
6.网站接收浏览器发来的数据之后,使用自己的私钥将信息解密取出密码,使用密码解密浏览器发来的握手消息,并验证HASH是否与浏览器发来的一致。
7.使用密码加密一段握手消息,发送给浏览器。
8.浏览器解密并计算握手消息的HASH,如果与服务端发来的HASH一致,此时握手过程结束,之后所有的通信数据将由之前浏览器生成的随机密码并利用对称加密算法进行加密。
这里浏览器与网站互相发送加密的握手消息并验证,目的是为了保证双方都获得了一致的密码,并且可以正常的加密解密数据,为后续真正数据的传输做一次测试。
备注:非对称加密算法用于在握手过程中加密生成的密码,对称加密算法用于对真正传输的数据进行加密,而HASH算法用于验证数据的完整性。由于浏览器生成的密码是整个数据加密的关键,因此在传输的时候使用了非对称加密算法对其加密。非对称加密算法会生成公钥和私钥,公钥只能用于加密数据,因此可以随意传输,而网站的私钥用于对数据进行解密,所以网站都会非常小心的保管自己的私钥,防止泄漏。
如何防劫持
对于HTTP
请求来说,常见的劫持有DNS劫持和内容劫持。
举个网上的例子,有人在知乎问过一个问题。
在浏览器输入如下域名https:// www.zhihu.com那浏览器要打开这个网站,首先要解析域名www.zhihu.com,结果这个域名被黑客劫持到他的私人服务器1.2.3.4,结果我的浏览器和他 的私人服务器1.2.3.4建立SSL连接,他的服务器1.2.3.4也和www.zhihu.com建立SSL的连接,我收发的数据都通过他的服务器1.2.3.4中转,也就是黑客的服务器1.2.3.4相当于一个https代理服务器,结果我收发的所有数据,他都能看到。可能这样被劫持吗?
这个黑客的攻击就是通常说的中间人攻击,跳转1.2.3.4就是DNS劫持,DNS被劫持到一个非源端的IP上。我们根据上文SSL握手的流程来分析一下,这种可能性是否存在。
首先如果黑客要跟你的浏览器建立SSL连接,那么他需要有一个CA证书,而通常系统内置根证书都是大型机构的根证书,几乎无法伪造。如果非要做一个只能是自签名证书。
浏览器拿着对方的自签名证书和系统证书进行校验,结果一定是如下图所示:
如果他要假冒其他机构颁发证书,因为没有颁发机构的秘钥,那么这个证书的指纹一定没办法对上,还是一样会报警。
除非用户自己主动导入一个自己信任的证书。
记住,不要随便安装受信任证书,否则HTTPS也帮不了你。我们平时为了调试HTTPS
请求,使用Charles/MitmProxy进行抓包,也需要在手机端导入一个证书,让用户选择信任安装,目的就是将Charles/MitmProxy作为中间人代理,如果没有用户信任安装证书的过程,也同样无法解析HTTPS的请求包。
还有人就说了,我可以让用户回落到HTTP
协议啊,中间人用HTTPS
跟服务器通信,然后用HTTP
跟客户端通信——要知道大部分用户在地址栏输入URL时,并没有指定协议的习惯,都是打www
开头而不是打https://www
开头,能用HTTPS
全是Web+Server上80端口301+Location到HTTPS
的功劳。
看起来似乎中间人充当了一个替换页面里HTTPS
资源到HTTP
的反向代理,好像可行性还是很高。
但是只要利用HSTS(HTTP+Strict+Transport+Security,RFC6797)就可以解决这个问题。通过在HTTP+Header中加入Strict-Transport-Security的声明,告诉浏览器在一定时间内必须通过HTTPS
协议访问本域名下的资源。
这种情况下,只要用户曾经在安全网络环境下访问过一次某站,中间人在指定时间内也无法让其回落到HTTP
。
解决完DNS劫持,再看内容劫持就简单多了。
你作为一个中间人,你没有服务器私钥A,是不能解密客户端发送的内容的,如果你没有客户端自己生成的密钥B,所以你也不能解密客户端发过去的内容的。
总结:
1.CA证书保证了公钥的可靠性。
2.服务端私钥+公钥的非对称加解密保证了客户端生成的随机数传输安全,不会被中间人拦截获取。But,非对称加密对服务端开销大。
3.所以利用随机数的对称加密保证后续通讯的安全性,也可以降低服务器的解密开销。
4.HTTPS只针对传输内容进行加密,保证的是客户端和网站之间的信息就算被拦截也无法破解。如果不是全站HTTPS,仅仅只是在登录页采用HTTPS,那些HTTP连接的页面同样是危险的,从HTTP->HTTPS跳转依然可能被劫持。国内的部分银行就是这样,对安全性的考量还比不上百度,百度早就全站HTTPS了。
参考
作者:superMaryyy
链接:https://juejin.im/post/5b762e726fb9a009c72cb73f
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。