您的位置:首页 > 理论基础 > 计算机网络

从运营商小广告到HTTPS

2016-07-21 21:07 337 查看
相信很多人都试过这样的经历,浏览一个正常的网站时,右下突然角弹出一堆小广告,而且这些广告的内容和你浏览的网站格格不入:



前几天还有某微博用户爆料访问github时居然也有广告:



又或者,你有没有试过因为不小心输错了某个网站的网址,出来一堆不堪入目的广告内容?

我今天还特意在家里试了一把,故意输入一个乱七八糟的网址,出来的页面让我无语,各种小广告,而且连续故意输错几个网址,都是这样:



上面说的几个事情,未必但很有可能就是运营商DNS劫持。事实上,运营商劫持几乎到了明目张胆的地步,尤其是一些N级小电信运营商。对运营商劫持的一些实际例子的危害,感兴趣可以看看这篇文章

什么是DNS劫持

DNS劫持的概念我就不抄书本了,大致原理其实非常简单。

说到DNS,肯定跟域名有关系。我们都知道在浏览器输入一个网址,首先要经历DNS查询,攻击方通过劫持DNS,给你返回一个假的服务器IP(攻击方的服务器),这时候你访问的就不是你要的服务器了。而攻击者为了更好地伪装,往往充当一个“代理”角色,把你的请求转发给真实地服务器,真实服务器把内容返回到攻击者,攻击者在这些内容里面做些手脚,比如放进去一些广告、脚本等等,再发送给访问者。访问者看到的内容便是被改动过的了。



DNS劫持的方法有很多,DNS服务器被黑,直接黑进你的电脑里改hosts文件等等,或者运营商偷鸡摸狗在DNS上搞鬼都是很正常的事……

运营商DNS劫持,其实大部分时候危害不大,最多的就是想钱想疯了,插入些小广告。但是如果是黑客恶意的劫持,那危害就大了,因为页面访客访问的内容是攻击者控制、篡改了的,而且往往非常隐蔽不好发现,web用户分分钟任人宰割。

HTTP的安全缺陷

之所以DNS一旦被劫持用户就变成任人宰割的小鸟,根本原因在于HTTP协议本身的一些安全缺陷。

明文传输

http协议本身不具备加密功能,通信过程中只要数据包被攻击者抓取,通信内容就可以直接被读取。例如你随便连了一个没有密码的WiFi,以为白捡了免费的网,殊不知你的上网内容很可能早就被被人看到了,如果你访问的网站没有使用HTTPS,那么你在上面输入的用户名、密码、银行卡信息可能已经被监听者收入囊中。



监听的过程其实就是网络抓包过程,什么?搞技术的不知道什么是抓包?我就不说wireshark、sniffer这些了,fiddler你总听说过了吧?

不验证身份

当你访问
http://www.qq.com
时,其实你是保证不了收到的内容一定是从腾讯的服务器来的。一个很简单的比方:攻击者克隆了一个一模一样的腾讯网,然后因为某种原因(DNS劫持),你访问腾讯网时的IP被解析到了这个克隆网站,这时候你访问的就是这个克隆网站。

同理,访问者的身份也是很容易伪装的,服务器也不能确定通信的对方一定是合法的访问者。



没有数据完整性校验

在HTTP请求或响应发送出去之后,到对方接收到信息之前,内容遭到攻击者的篡改,对方是没有办法获悉的。换句话说,没有任何办法可以确认,发送出去的消息和接收到得消息前后是一致的。



为了保证内容的一致,有些网站使用MD5和SHA-1等散列值校验方法,确保用户收到的内容是正确的。

例如某下载网站提供文件的以下相关数据,确保用户下载的文件没有被修改。用户只要在下载了文件之后自行计算文件的散列值,并和网站提供的散列值对比,从而得知文件有没有被修改过。



但是,这种检查方法取决于用户本人的亲自检查,浏览器无法自动帮助用户检查;再者,MD5本身被改写的话,用户是没有办法意识到的。

HTTPS

要解决上面的三个问题,需要引入三个机制:

1、 内容加密 让监听者拿到消息也看不懂



2、 证书 用一个权威的机构(CA)和证书来证明通信双方的身份(CA的概念会在后面解释)



3、 完整性校验

为了解决这三个问题,引入了HTTPS。

披着SSL外衣的HTTP

HTTPS全称是Hyper Text Transfer Protocol over Secure Socket Layer,它并不是一个新的协议,其本质上是在HTTP和TCP之间加了一层SSL/TLS协议。 通常,HTTP是直接和TCP通信的。



当使用了SSL时,就变成了HTTP先和SSL通信,再由SSL和TCP通信。



前面所说的
加密
证书
完整性校验
便由SSL来完成。

加密技术

讨论SSL之前,有必要了解一下加密方法。SSL采用了对称密钥加密和非对称密钥加密混合的加密处理方式。对于这两种加密算法,本文不做过多阐述,只简单介绍,因为这里面的内容可以写一本书了。

对称密钥加密

对称密钥加密也叫共享密钥加密。所谓对称,也就是加密和解密双方都使用同一把钥匙。

既然双方密钥一样,所以存在密钥发送过程,发送途中只要攻击者也拿到这个密钥,那么就可以随时破解通信内容了。

既然发送密钥有被窃听的风险,但不发送吧对方又不能解密。所以,安全地发送密钥给对方,就成了通信的关键。

非对称密钥加密

非对称密钥加密也叫公开密钥加密。这种加密方式有两把密钥,一把是私有密钥(私钥),一把是公开密钥(公钥)。公钥可以随意发布,谁都可以拿到,并用它来加密内容,这个加密内容只有私钥可以解开,而私钥是不公开的。

使用公开密钥加密方式,发送密文的一方使用对方提供的公钥加密内容,这个加密内容只有对方收到后,使用私钥才能解密。利用公钥和密文进行解密就目前的技术来看还不太现实,所以这种方式目前是非常安全的。

常见的非对称加密算法有RSA等,感兴趣的可以看阮老师的RSA算法原理(一)和RSA算法原理(二)。

混合加密机制

上面说的两种加密方法,对称加密过程相对简单,但是密钥传输不当的话安全性没法保证;非对称加密过程安全,但是实现过程会更复杂、消耗更多时间,效率会低。

所以HTTPS采用了两者并用的加密机制,这里面包含两步:

1、 使用非对称密钥加密方法来传输对称密钥



2、 使用第一步中传输的对称密钥来进行消息加密



第一步完成后,对称密钥(上图黄色的钥匙)没有第三方可以获取到,保证了加密秘钥不会被第三方窃取;同时第二步使用对称密钥使得加密解密过程更加快速。

证书

确保了内容加密之后,通信实际还是不安全的,因为,一方面客户端收到公钥,但还是无法证明收到的公钥就是它预想的那台服务器发行的公钥。

因为坏人自己可以生成公钥/私钥冒充服务器端发给客户端,然后中间窃取消息再用真正的公钥私钥转发给真正的服务端(中间人攻击),这样就不安全了。

说白了,搞不好和你加密来解密去的对方到头来就是一个攻击者。

为了解决这个问题,SSL协议引入了数字证书认证机构(CA) + 数字证书的机制。这里简单解释下两个名词:


CA:Certificate Authority,是证书的签发机构,是负责签发证书、认证证书、管理已颁发证书的机关。简单的说,CA是一个得到社会普遍认同的权威机构,通信过程中,只要CA告诉你对方是合法的,那么就是合法的,同时对方提供的公开密钥也是没有经过修改替换的。

数字证书:也叫公开密钥证书、证书。数字证书用于实现身份识别和电子信息加密。数字证书中含有密钥对(公钥和私钥)所有者的识别信息,通过验证识别信息的真伪实现对证书持有者身份的认证。


CA认证的过程简述如下:

CA自己本身有一个对称加密机制,即已生成私钥和公钥。自己留有
CA私钥
,而
CA公钥
已经植入大多数浏览器中。

服务器生成一对非对称密钥,自己留有
服务器密钥
,把
服务器公钥
提交给CA。

CA使用自己的
CA私钥
服务器公钥
进行
数字签名
(实际就是加密),成为
公钥证书
,还给服务器。

通信的时候,服务器把
公钥证书
发给客户端。

客户端拿到
公钥证书
后,使用步骤1中的
CA公钥
对这个
公钥证书
进行
数字签名
(实际就是解密)。

如果签名(解密)成功,就可以得到
服务器公钥
,并且可以确定这个公钥是真实有效的服务器发放的。

客户端使用步骤6中得到的
服务器公钥
加密消息,这个消息只有步骤2的
服务器密钥
可以解密。

在《图解HTTP》(【日】上野宣著 于均良译)这本书中有个图把这个过程阐述得非常清晰明了:



绿色图标

前面说到,
CA公钥
已经植入大多数浏览器中,正是因为这点访问者可以验证服务器及其公钥的真实性,你可以查看你的浏览器中已有的CA密钥:



我们在浏览一些申请了标准正规的证书的网站时,地址栏会有绿色的图标,例如某网站:



绿色图标的初衷是为了提醒用户注意被钓鱼,但是实际情况中用户会不会去关注,就是个问题了。

CA被攻击

试想,当ZF被人收买时,你还会相信ZF吗?

同样地道理,我们相信CA,是建立在CA信用绝对可靠、大家都相信的情况下的。但是,当CA本身遭到攻击,颁布了伪造的证书后,影响就非常大了,例如下面这个例子:



这种情况下,虽然有可将证书无效化的证书吊销列表机制,以及从客户端删除根证书颁发机构的对策,但是距离生效是需要一段的时间的(例如取决于用户是否升级浏览器、是否为系统打补丁),在这段时间内,有多少用户蒙受损失,是难以估量的!

自签名证书

SSL是基于openssl这个开源程序的,其实每个人都可以给自己颁发数字证书,这时候自己就是CA了。当然因为你自己一定是权威的机构,所以你给自己颁发的这个证书是不被浏览器认可的,例如我国某大型电商网站的证书:



客户端证书

前面说的都是服务器证书,用来验证服务器身份的。然而反过来,服务器想要验证客户端真实性的时候,怎么办呢? 其实原理是一样的,这时候就需要客户端证书,整个验证过程和前面的服务器证书验证过程基本一致,这里不再赘述。


客户端证书的一个典型例子:你有去过银行开网银吧?很多银行都会给你一个巨大的“U盘”,让你登陆网银的时候插上去,这个“U盘”里便保存着客户端证书。


完整过程

到这里已经可以梳理出一个HTTPS通信的完整过程。

再次从《图解HTTP》(【日】上野宣著 于均良译)这本中偷来一张神图,解释了仅使用服务器证书时建立HTTPS通信的过程:



客户端和服务器协商加密组件,这里面其实包含了两步: 1) 客户端发起SSL通信,告知服务器客户端支持的加密组件(加密算法、密钥长度)列表等等信息 2) 服务器从上面的加密组件列表中选取,并告知客户端

服务端给客户端发送服务器的
公钥证书


客户端从
公钥证书
中取出
服务器公钥
用这个公钥加密一个客户端的
pre-master secret


客户端发送这个加密了得
pre-master secret
给服务器

服务器解密
pre-master secret
得到
master secret


这时候客户端和服务端都有了一个
master secret
,可以把它理解为对称加密密钥,并且这两个对称密钥没有第三者知道,之后的通信内容,就用这对密钥加密就行了。

性能

HTTPS通过使用SSL/TLS,解决了加密、证书、完整性校验等安全问题,同时也带来了明显的性能问题:

1、 SSL握手延迟

在传统的TCP三次握手的基础上,还必须进行SSL通信,至少增加一次RTT,这个时间的消耗有可能是非常大的(例如移动端网络),取决于客户端与服务端通信链路的物理距离和中间节点数量。

2、 加密解密消耗

和明文通信相比,SSL增加了加密和解密过程,这个过程对CPU、内存、时间的消耗也是不可忽视的。

以上两点,是其他条件不变的前提下,从HTTP迁移到HTTPS必然带来的性能问题。为了弥补时间的消耗,很多网站现在已经开始使用SPDY、HTTP/2,篇幅有限,有机会再介绍这两个东西。

再说回DNS劫持

说到这里,为什么HTTPS能够有效的解决DNS劫持,应该就很好解释了。

在域名被劫持的情况下,客户端得到一个攻击者的IP,客户端通过这个IP找到攻击者的服务器,要求建立HTTPS通信,因为攻击者没有真实服务器的证书和私钥,把伪造或自签名的证书提供给客户端,是得不到CA的认可的。

劫持者是可以拿到真实服务器公钥的,所以可以窃取真实服务器发给客户端的内容并解密的,但是他没有真实服务器的私钥,所以即使偷到这个内容,也只能原封不动地传给客户端,乖乖充当一个代理者。如果劫持者对这个内容做了修改,在客户端那里是无法通过校验的,因为只有真实服务器私钥加密的内容,才能在客户端那里被识别。

由此可知,部署和使用HTTPS的过程中,服务器的私钥是非常非常重要的,只有服务器自己能保留和知道,如果泄露了,安全就等同虚设了。

想说但没说的

下面的内容跟HTTPS、SSL密切相关,但是不影响基本原理的理解,感兴趣可以自行去了解:

数字签名/数字摘要

SSL与TLS的关系

openssl漏洞,例如去年轰动全球的“心脏滴血”(heartbleed)漏洞

SSLstrip攻击

运营商DNS和HTTP劫持的区别
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: