
为什么要接入 HTTPS—HTTP 的安全风险
HTTP 协议是一个非常简单和高效的协议,互联网大部分的主流应用默认都是使用的HTTP。由于性能和上个世纪 90 年代使用环境的限制,HTTP 协议本身并不是一个为了安全设计的协议,既没有身份认证,也没有一致性检验,最头疼的是,HTTP 所有的内容都是明文传输的。
另外一方面,互联网的发展也是日新月异,各种 HTTP 应用不断地渗透到人们生活的方方面面。不管是社交、购物、金融、游戏、还是搜索,这些 HTTP 服务都能带给人们极大的便捷,提升生活质量和效率。
显然,HTTP 和人们生活及经济利益密切相关,遗憾的是,它不安全。也就意味着这里一 定潜藏着巨大的安全隐患。这些隐患又集中表现在如下两方面:
1、隐私泄露
由于 HTTP 本身是明文传输,用户和服务端之间的传输内容都能被中间者查看。也就是说 你在网上搜索、购物、访问的网点、点击的页面等信息,都可以被「中间人」获取。由于国人大多不太重视隐私的保护,这里的风险比较隐性,伤害后果也不太好定量评估。已知的一些比较严重的隐私泄露事件包括:
1、QQ 登陆态被不法分子窃取,然后在异地登陆,进行广告和欺诈行为。
2、用户手机号和身份信息泄露。
3、用户网上行为泄露。比如搜索了一所医院,很快就会有人打电话进行推广(非效果广告)。
2、页面劫持
隐私泄露的风险比较隐蔽,用户基本感知不到。但另外一类劫持的影响就非常明显非常直接了——页面劫持,也就是直接篡改用户的浏览页面。有很多页面劫持很简单粗暴,直接插入第三方广告或者运营商的流量提示信息。
但也有一些劫持做得比较隐蔽,换成 HTTPS 访问,就没有这个工具页面,显然是被劫持了。
3、劫持路径及分类
那劫持到底是如何产生的呢?从技术上来讲比较简单,在内容经过的地方进行监听篡改就行了。但要想把整个劫持的产业链条摸清楚,需要深入黑产内部,比较困难。有一点可以肯定的是,劫持大部分都是在中间的网络节点发生的,又叫「中间人」(MITM, man in the middle)。
由于信息传输都需要经过上述的「中间人节点」,它们又拥有信息的读写权限,如果信息没有加密,也没有校验,那么想要查看隐私,篡改页面,对于「中间人」来说可谓是轻而易举。
那劫持又有哪些主要的分类呢?根据劫持路径划分的话,主要三类:
DNS 劫持,客户端劫持和链路劫持。 根据我们的不完全统计,业务遇到的绝大部分劫持 (90%)都属于链路劫持。
HTTPS 是解决链路劫持的核武器
HTTPS 为什么能很好的解决链路劫持呢?主要是三大武器:
1、身份认证—防假冒,防抵赖
每次建立一个全新的 HTTPS 连接时,都需要对身份进行认证,确保用户访问的是正确的目的网站。
2、内容加密—防窃听
内容加密意味端对端的通信内容全都是密文,中间人无法直接查看到明文,HTTPS 所有的应用层内容都是通过对称加密来实现加密和解密的。
3、一致性校验—防篡改
通过对数据和共享密钥的 MAC 码来防止中间者篡改消息内容,确保数据的一致性。
四、HTTPS 普及之痛
事实上 HTTPS 1995 年就诞生了,是一个非常古老、成熟的协议。同时又能很好地防止内容劫持,保护用户隐私。但是为什么一直到今天,还有大部分的网站不支持 HTTPS,只使用 HTTP 呢?
影响 HTTPS 普及的主要原因可以概括为两个字:「慢」和「贵」。
1、慢
在未经任何优化的情况下,HTTPS 会严重降低用户的访问速度。主要因素包括:
网络耗时。由于协议的规定,必须要进行的网络传输。比如 SSL 完全握手,302 跳转等。最坏情况下可能要增加 7 个 RTT。
计算耗时。无论是客户端还是服务端,都需要进行对称加解密,协议解析,私钥计算,证书校验等计算,增加大量的计算时间。
2、贵
HTTPS 的贵,主要体现在如下三方面:
1、服务器成本。HTTPS 的私钥计算会导致服务端性能的急剧下降,甚至不到 HTTP 协议的十分之一,也就是说,如果 HTTP 的性能是 10000cps,HTTPS 的性能可能只有几百 cps,会增加数倍甚至数十倍的服务器成本。
2、证书成本。根据证书个数及证书类型,一年可能需要花费几百到几百万不等的证书成本。
3、开发和运维成本。HTTPS 协议比较复杂,openssl 的开源实现也经常发生安全BUG, 包括协议的配置,证书的更新,过期监控,客户端的兼容等一系列问题都需要具备专业背景的技术人员跟进处理。
公司新上线了一个微信小程序,在测试环境以及小程序体验版上测试一切正常,但上线之后,页面加载尤其慢。
经过运维排查,所有的请求到达服务器后均在1s内处理完成并响应,偶尔有2-3s的请求,极少。
既然服务端处理请求没有问题,那么,加载可能出现在小程序本身或网络延迟,但后者可能性较低。于是,使用fiddler抓包,其中一个加载较慢的请求结果如下:
关键时间节点如下:
· 客户端与服务器完成tcp链接时间是11:31:35(时分秒)
· 客户端开始向服务端发送请求的时间是11:31:36(时分秒)
· 服务端接收到请求的时间是11:31:36(时分秒)
· 服务端开始响应的时间是11:31:46(时分秒)
也就是说,从服务器接收到请求到开始响应耗时10s,可这跟运维查看的日志结果不符!
鉴于上面的抓包结果和生产日志结果相悖,决定使用curl对耗时较长的http请求进行分析。
运行结果如下
对应的结果含义如下:
· time_namelookup :DNS 域名解析的时候,就是把 https://zhihu.com 转换成 ip 地址的过程
· time_connect :TCP 连接建立的时间,就是三次握手的时间
· time_appconnect :SSL/SSH 等上层协议建立连接的时间,比如 connect/handshake 的时间
· time_redirect :从开始到最后一个请求事务的时间
· time_pretransfer :从请求开始到响应开始传输的时间
· time_starttransfer :从请求开始到第一个字节将要传输的时间
· time_total :这次请求花费的全部时间
那么对应的时间点应该是:
· DNS解析耗时:0.005s
· TCP建立连接的耗时:0.035-0.005=0.03s
· SSL握手完成耗时:3.8-0.034=3.7s
· server处理数据的时间:3.8402-3.8401=0.0001s
· 总体的耗时:14.5s
emmm,按照这个结果来看,从服务器开始响应到传输完成一共耗时14.5-3.8=10.7s。
那么这里问题又来了,这结果跟fiddler的结果完全相反,到底是在哪个环节出了问题?
fiddler的结果显示从服务器接收到请求到开始响应耗时10s,是服务器处理请求消耗了10s;而curl显示服务器处理请求只用了0.0001s,响应开始到结束耗时10.7s。到底哪个是对的,难道是根据本身有问题?
于是在跟运维同事一波交流之后,得到请求流转过程如下:
客户端<---------->CDN服务器<---------->Nginx代理<---------->应用服务器<---------->DB
弄清请求流转过程之后,手动发送请求,实时查看Nginx和应用服务器日志,发现请求发出后,间隔一段时间(10s左右)Nginx日志才有输出,接着很快App Server日志也有输出(包括请求和响应)。事实就摆在眼前,是CDN服务器<---------->Nginx代理之间出现了问题,具体是为什么目前还不清楚。
那么fiddler和curl抓包的结果如何解释?
fiddler:从服务器接收到请求到开始响应耗时10s,是正确的。
curl:服务器处理请求只用了0.0001s,响应开始到结束耗时10.7s。这里就有问题了,要想解释得通,只能说time_pretransfer和time_starttransfer是CDN服务器的响应时间,由于配置了CND,在向小程序应用服务器发送请求时,会先请求到CDN服务器此时CDN服务器很快就响应了客户端的请求,但CDN服务器在转发请求到Nginx代理时出现了延迟,因此在curl的请求结果中才会看起来像是响应开始到响应结束耗时较长。
至于为什么请求从CND服务器到应用服务器会出现延迟,目前还没有结论。待更新
http://blog.51cto.com/h2ofly/1957171
http://developer.51cto.com/art/201704/536923.htm?foxhandler=RssReadRenderProcessHandler
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)