问题描述
都说https是在http和tcp两层之间加密,针对的是传输过程,只有客户端和服务端才能解密,变成明文。但是又有很多人说,https协议下,用get请求不加密,需要用post才会加密,而且这么说的人很多。
我的疑惑就是,如果把整个数据都加密了,是不是无论get和post都是一样的?
因为不懂抓包技术,所以比较好奇。https传输下,抓包者抓到的都是乱码? 能抓到URL,或者header之类的信息嘛?
再补充一个问题,网上还有一种中间人抓包模式?
如果有人在我和服务器之间抓包,伪造证书,搞这个中间人模式,那么浏览器是不是直接提示证书不安全?
如果浏览器也分辨不出来的话,是不是ssl证书质量不过关?
如果ssl证书质量过关,浏览器还无法分辨的话,那https岂不是一点用没有?该抓还抓,该截还截?
正文
首先直接说结论,https安全通信模式,是使用TLS加密传输所有的http协议。再重复一遍,是所有!
通常将TLS加密传输http这个通信过程称为https,如果使用协议封装的逻辑结构来表达就是:
IP + TCP + TLS +【HTTP】
其中用【】括起来的http是完全被加密保护起来的。
既然http被完全加密起来了,那使用https加密传输信息,途径互联网的时候,互联网上的第三方可以知道我们在访问什么网站吗?
可以的!
你可能会很惊奇,既然http已经被完全加密了,怎么第三方还会知道我们访问什么网站?
我们在访问一个网站时,比如www.zhihu.com,首先会使用DNS将网站的域名解析成IP地址,然后才可以使用IP地址来网站建立TCP连接、TLS安全连接。由于DNS是不加密的,所以第三方只要通过读取明文的DNS查询与响应报文,就可以知道我们再访问哪些网站。
读者会心生一计,如果我将域名与IP地址的对应关系,保存在本地的host文件里,那么下次就不需要发送DNS查询报文了,那么第三方就无法知道我们在访问什么网站了,对吗?
好主意!
但是第三方可以通过服务器的IP地址,使用DNS反向解析得到服务器的域名。
像知乎这样的网站通常会使用边缘加速,一个边缘加速服务器IP地址会host成千上百个网站,使用DNS反向解析会返回上千个域名,对吗?
对的!
但是我们与服务器TLS握手时,会在Client Hello报文的“TLS Extension”里携带一个明文的“Server Name Indication”用于指示边缘服务器我们真正要访问哪个网站,第三方读取一下SNI就会得到答案。
即使我们的浏览器有点古老,不支持SNI扩展,第三方就没有办法知道我们访问哪个网站了?
当然可以知道,因为TLS握手时,服务器推送过来的Server Hello里会携带明文的证书,证书里会清清楚楚地标明客户端正要访问什么网站。
现在互联网上大体有以下三种通信模式:
对于不安全通信、安全通信其实非常好理解,它们分别对应http与https。
http的协议封装的逻辑架构是这个样子的:
IP + TCP + HTTP
https的协议封装的逻辑架构是这样的:
IP + TCP + TLS +【HTTP】
两者都使用http协议通信,只是由于后者有TLS的撑腰(安全加密),才使得https通信安全。
不完全安全通信又代表什么呢?
https+ http
读者会很纳闷,如下图所示,访问微信公众平台明明使用https://的协议前缀(Prefix),应该全部使用https完全安全通信,而不会使用https+ http混合通信,对吗?
理论上是这样的,但现实有时却偏离理论。理想是丰满的,现实却是骨感的。
当我们使用https访问https://www.example.com时,服务器返回的内容是https加密的,这一点问题没有,当浏览器准备显示的时候,发现要显示的内容是一个链接资源,而这个资源的链接地址是:http:// www.example.com,于是浏览器使用不加密的http,去访问服务器,将链接所对应的资源拉下来,然后显示在浏览器上。
最终,我们看到的页面由两部分组成:https的安全页面 + http的不安全页面,我们称之为混合页面(Mixed Content)。
为何会产生混合页面?
最早的服务器提供的是http服务,很多资源的链接地址无意中使用了绝对路径,比如“http:// www.example.com”,在这个绝对路径中,不仅仅包含了路径“www.example.com/*****”,同时还包含了访问协议类型“http”。
这种绝对路径在http通信用的好好的,用于指示浏览器使用TCP 80端口访问服务器。
当https慢慢成为主流通信方式,越来越多的公司开始从http向https的迁徙,很多服务器跑在了有TLS保护的443端口。
当我们访问“https:// www.example.com”,浏览器可以协议前缀,准确地知道我们要访问的是服务器的443端口。
一旦链接使用绝对路径,浏览器就会乖乖地使用“http://www.example.com/*****”访问服务器的80端口。
如何解决混合页面问题?
将所有链接的绝对路径改写为相对路径“//www.example.com/*****”。
如果浏览器使用https访问服务器,会默认添加成“https: //www.example.com/*****”。
如果浏览器使用http访问服务器,会默认添加成“http: //www.example.com/*****”。
当你意识到自己访问的页面有一部分是明文传输时,会否大吃一斤?
混合页面的存在,网站的owner肯定是知道的,甚至故意将一部分静态页面(图片、视频、音频)使用http传输,以减轻服务器处理加密报文的负担。
有潜在的读取浏览器cookie的动态页面(JAVAscript),绝对不能使用明文传输。
使用完全加密的https通信时,则没有那么麻烦,所以将网站采用完全https通信是最明智的选择。
再来回顾上一篇的问题,https会加密所有的http内容,但是当浏览器尝试去拉取不安全(http)链接时,此时已经不是安全通信了。当抓包时,就会出现在一堆加密报文中,穿插着不加密的报文,读完这两篇文章,希望这个问题不再是问题。