2020年蝙蝠纪元,二毛一如往常的呆在家中,不敢外出去浪。
为排解心中之闷,二毛抽了一口老烟,熟练的打开了全球最大的同性交友网站,准备假装了解下最近流行的项目...
只听啪的一声回车键,哪知浏览器蹦出这么一个画面...
这是怎么回事?二毛有点疑虑,突然门外传来一阵急促的敲门声,二毛起身前去开门...
二毛在电脑前敲入京东的域名(https://www.jd.com/),果不其然,也跳出跟Github一样的安全提示。随后二毛一顿搜索,终于知道了原因。
HTTP
要搞清楚上面的问题前,我们先要知道 HTTP 协议。
HTTP是什么呢?引用百科的解释就是:
即超文本传输协议(Hypertext transfer protocol),是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。请求和响应消息的头以ASCII码形式给出;而消息内容则具有一个类似MIME的格式。这个简单模型是早期Web成功的有功之臣,因为它使得开发和部署是那么的直截了当。百科
简单来说,HTTP就是浏览器(客户端)和网站(服务端)之间传输信息使用的协议。
打个比方,就像读书的时候,你跟前排同学传纸条前,你总是要先戳一下前排同学的后背,然后前排同学就会往后伸出一只手来,这时候你就可以把纸条放在她手心。她看完后会在纸条写上文字,然后再次弯手,你再伸手拿纸条。这就完成了一次通信的过程。
你戳她后背,她向后弯手的动作(像极了爱情??),就像是一种准备通信的规则,换句话说就是一个传纸条的协议。而在网络世界中,浏览器和网站通信,用的就是一种名为HTTP的协议。
HTTP特别简单,它部署快捷,传输效率高,推动了互联网的巨大发展。
HTTPS
为什么会有 HTTPS?
HTTP是如此简单,简单到连传输的内容都没有处理,直接使用明文传输的,但是这无疑会给信息的安全带来重大的隐患。稍微懂点抓包的且有相关权限的,就可以把你跟网站通信的内容看的一清二楚。
再举个例子:
教室里,第五排的小明想给第三排的小红传情书,必须得经过第四排的同学接力传递。这样一来就会产生下面几个问题:
-
窃听:纸条内容被第四排同学知道了,并向老师举报,导致小明因骚扰女同学而被辍学。
-
篡改:纸条被第四排同学改写了,把"想跟你一起起床"改成"想跟你一起睡觉",导致小红看后怒火中烧,直呼渣男。
-
破坏:纸条被第四排同学破坏,导致小红无法辨认内容,误以为小明恶作剧扔了一团废纸,而怒发冲冠,拳脚相加。
-
伪装:第四排同学直接伪装成小红回复小明,表示愿意交往。导致下课时小明牵小红的手,被一剑封喉。
由于传纸条通信规则协议的不完善,使得第四排同学也就是中间人有机可乘干坏事,造成了以上四种不良结果。
映射到网络世界,网络通信的链条如此曲折冗长,中间极大可能也有诸多牛鬼蛇神、心怀不轨的人,会千方百计的对你传输的信息拦截,然后对信息进行窃听、改造、破坏甚至伪装。
使用 HTTP 协议传输信息无异于在网络世界裸奔,但是现在世界上仍然有许多网站使用的是 HTTP(当然大部分是没什么重要信息的网站)。基于此,Google浏览器已经把使用 HTTP 协议的网站,标为了不安全,以进一步提示用户可能存在的风险。
随着现代社会人们对隐私安全的要求越来越高,HTTPS 便顺应时代潮流,应运而生。
什么是 HTTPS?
HTTPS (全称:Hyper Text Transfer Protocol over SecureSocket Layer),是以安全为目标的 HTTP 通道,在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性 [1] 。HTTPS 在HTTP 的基础下加入SSL 层,HTTPS 的安全基础是 SSL,因此加密的详细内容就需要 SSL。HTTPS 存在不同于 HTTP 的默认端口及一个加密/身份验证层(在 HTTP与 TCP 之间)。这个系统提供了身份验证与加密通讯方法。它被广泛用于万维网上安全敏感的通讯,例如交易支付等方面 。百科
总结起来就是:基于HTTP协议,通过 SSL 或 TLS 的封装,使得 HTTPS 有了以下几个功能:
-
加密数据
-
验证对方身份
-
数据完整性保护(即可以得知数据有没有被破坏或篡改)
有了这几个功能,我们再来重新审视小明和小红传纸条的例子:
- 窃听 --- 有了 加密数据 的功能,小明表示妈妈再也不用担心我被辍学了!
- 篡改 -- 有了 数据完整性保护 的功能,小明表示妈妈再也不用担心我被大呼渣男了!
- 破坏 -- 有了 数据完整性保护 的功能,小明表示妈妈再也不用担心我身受重伤了!
- 伪装 -- 有了 验证对方身份 的功能,小明表示妈妈再也不用担心我英年早逝了!
总结:有了 HTTPS 功能的保驾护航,中间人再也不会从中作梗,小明可以放心写情书了!
正当二毛准备继续侃侃而谈时,二丫的电话响了...
二毛隐约听到二丫电话那头的人正操着广普,语气有些焦灼的说着几个关键词:房租、一定...
二丫挂掉电话,对二毛邪魅一笑...
开始之前,我们先了解一些前置技术。
前置技术
1 对称加密
定义:一种加密算法,只有一个密钥,这个密钥既可以用来加密数据,又可以用来解密数据。
优点:加解密速度快。
缺点:由于只有一个密钥,应用场景不广泛。
2 非对称加密
定义:也是一种加密算法,有两个密钥,一个称为公钥,另一个称为私钥。其中公钥可以广而告之,私钥需要自己妥善保存。公钥可以加密数据,然后用私钥解密;反过来,私钥也可以加密数据,用公钥来解密。
优点:由于公钥和私钥可以互相加解密,应用场景广泛。
缺点:加解密速度较慢。
3 消息摘要:
定义:通过哈希函数,将任意长度的消息变成固定长度的短消息,且一个固定的内容无论经过多少次哈希得到的结果仍然是固定不变的,称为消息摘要。
应用场景:可将长消息缩短,加密处理起来更快。
4 数字证书:
定义:由CA(一个权威的认证机构)颁发的一种证书,里面含有可以标识你身份的信息,类似于我们的身份证。
注:证书是必须由服务端主动向CA申请的。服务端(假设为网站)提供自己的域名等信息,接着CA会使用它们的私钥对内容进行加密,然后作为数字证书返回给服务端。
应用场景:
身份证明。由于CA是权威的,他们的私钥会严格保存,公钥会广为公开,所以一旦服务端网站出示了数字证书后,我们就可以依据颁发证书的CA,找到对应的公钥,然后解密数字证书得到里面的域名信息,并比对当前访问的域名是否跟得到的域名一致,以此判断真假。
5 数字签名:
定义:只有信息的发送者才能生成的、别人无法伪造的一段字符串。
主要有两个步骤生成:
-
首先对要发送的内容进行消息摘要得到短字符串。
-
发送者再使用自己的私钥对该短字符串进行加密,就得到了数字签名。(当然也可以对整个信息做数字签名,但是经过消息摘要处理的信息会更少,加密更快。)
应用场景:
-
完整性保护:只要我们使用发送者的公钥解密数字签名,得到原摘要内容,再跟我们自己进行消息摘要的内容进行对比,就能判断,若一致,则说明信息内容没篡改破坏过。
-
不可抵赖性:由于发送者的私钥只有发送者自己知道,所以只要信息比对一致,就能证明这信息是该发送方写的。
看到这里,读者可能有点懵,那数字签名跟数字证书有什么不同?
-
数字签名一般是用户用自己的私钥加密摘要生成的,目的是为了数据完整性保护和不可抵赖性。
-
数字证书是使用CA的私钥加密你的信息形成的,目的是证明你的身份。
HTTPS的技术实现
在上集的例子中,小明给小红传纸条,但是小明的明文通信可能会被第四排同学窃听、篡改、破坏、伪装,而对应的解决方法就是使得通信规则能有这三个功能:加密数据、数据完整性保护、身份验证。
那该如何使得通信规则有这三个功能?小明在研究了前置技术的内容后,受到启发,决定这样干:
(这里假设学校有个大队长(即CA)能够为学生信息做公证,即颁发数字证书,小明小红都已经申请了自己的数字证书。数字证书中包含自己的姓名、自己的公钥等信息)
1 在开始传对话内容前,小明就先传纸条请求小红的数字证书,请求时也把自己的数字证书传过去。
2 小红收到信息后,就用大队长的公钥解密得到信息,得知是小明请求与她传纸条,于是她含羞的把自己的数字证书回传了过去。
3 小明得到返回的数字证书后,也用大队长的公钥解密得到信息(信息含有小红姓名和小红公钥),比对姓名信息看是否为小红。如果不是小红,则不通信,如果是,进入下一步。
4 小明随机生成一串字符a,然后拿出小红的公钥,并用该公钥加密这串字符a,返回给小红。
5 小红收到信息就用自己的私钥进行解密,然后取出字符a,随后小红将内容 “同意传纸条” 用字符a作为密钥进行对称加密,得到密文后写入纸条中。另外,小红也对内容 “同意传纸条”进行消息摘要,随后用自己的私钥对摘要的内容进行加密得到数字签名,写入纸条署名处。
6 小明收到信息,用字符a作为密钥进行对称解密,得到内容“同意传纸条”。为了鉴别内容是否被破坏或篡改过,小明使用小红的公钥对署名的字符进行解密,得到消息摘要内容a,另外再将内容“同意传纸条”进行消息摘要得到消息摘要b,最后将摘要内容a和摘要内容b进行比对,如果一致,则说明没有破坏或篡改过。
7 通信继续。。
至此上面几个步骤,就完成了安全的连接和通信:双方都使用字符a作为密钥对内容进行对称加密,另外生成数字签名写在一旁用于校验内容。
身份验证的实现:
此前小明不是怕第四排同学伪装成小红回纸条信息吗?
现在有了数字证书的功能,在一开始准备传对话内容前就可以通过CA公钥解密数字证书,得出信息来辨别对方身份。
万恶的第四排同学(中间人)再也无法伪装女神小红了!
注:HTTPS机制非常重要的一点就是假定CA的私钥是安全的,如果泄露了,HTTPS的安全性机制将土崩瓦解。所以CA一般是大公司或组织,因为它们更有能力保护自己的私钥,因此浏览器信任的CA列表往往是一些知名CA。
数据加密的实现:
此前小明不是怕第四排同学窃听纸条信息吗?
现在因为有了前面的身份验证,也就确保得到了真实对方的公钥,并能利用该公钥加密传输即将用于对称加密对话内容的密钥(例子中的字符a)。只要这个对称密钥被安全传输了,后面进行纸条内容的加密也就被高效的实现了。
万恶的第四排同学(中间人)再也不无法偷看我的纸条小秘密了!
注:这里可能会有同学问,既然双方都知道彼此的公钥后,那为何不直接拿对方的公钥来加密自己要发出的信息?这个确实可以,但是却忽略了高效性,前面已经提到过,非对称加密算法比对称加密算法效率要低,考虑到后续通信的频繁性,所以最好使用对称加密来对通信内容进行加密。
数据完整性保护的实现:
此前小明不是怕第四排同学篡改或破坏纸条信息吗?
现在有了数字签名,可与原有信息进行对比,就可以判断纸条内容有无被更改或破坏了。
万恶的第四排同学(中间人)再也无法更改或破坏我对女神表达的情感了!
HTTPS的建立过程:
弄懂了上面小明传纸条的例子,再来理解访问使用 HTTPS 协议网站的建立过程,简直就是易如反掌!
建立安全的HTTPS通讯,可防止中间人攻击,这需要以下步骤:
1、服务端配置正确了对应的安全证书
2、客户端发送请求到服务端
3、服务端返回公钥和证书到客户端
4、客户端接收后会验证证书的安全性,如果通过则会随机生成一个随机数,用公钥对其加密,发送到服务端
5、服务端接受到这个加密后的随机数后会用私钥对其解密得到真正的随机数,随后用这个随机数当做密钥对需要发送的数据进行对称加密
6、客户端在接收到加密后的数据使用密钥(即生成的随机值)对数据进行解密并且解析数据呈现结果给客户
7、SSL加密建立。后续数据传输还将用到数字签名技术。。
百科
注:小明传纸条的例子和用户访问网站有点不同:小明小红互相传纸条需要双方互相进行身份验证;而用户访问网站,只是用户验证网站,网站不验证用户。但无论哪种情况,使用的底层技术都是上面几种,只是应用情况不同。
事件后续吃瓜
点击域名左边的感叹号标志,就能查看到该网站提供的证书信息。
可以看到这个数字证书的签发人信息,从电子邮箱可以知道 QQ。后续网传这QQ主人还是个初学计算机的高中生......
不过,“初学者”的猜测显然不符合常理,“凭一己之力搞坏网络”所需要的智商,和“拿自己QQ邮箱签名证书”所对应的智商,显然不在同一个位面上。这不符合常理,事出反常必有妖。
最近,这位号主也发话澄清了。。
晚上,二毛坐在电脑桌前,看着万家灯火,想象着二丫又搞懂了一些计算机知识点后,欣喜若狂、欢呼雀跃的样子,不禁感到欣慰。
他随后在电脑上敲下一行标题:跟零计算机基础的房东女儿讲了一下午的中间人劫持京东事件后,她感激涕零,决定给我免除房租。
哎,程序员的快乐,往往就是那么朴实无华、枯燥且乏味。
在用go开发web程序前,必须了解HTTP协议,对于没有接触过的人来说,强烈建议看下这两本书:《HTTP权威指南》和《图解HTTP》。
HTTP概述
我们平时上网,打开浏览器,输入网址后按下回车键,相应的Web页面就显示出来了。那这个过程到底是如何实现的呢?
先来看下面一张图:
上图很清楚的描述了一个用户访问一个web站点的过程。分为三步:
1. 通过客户端也就是浏览器输入URL网址,客户端通过DNS协议与DNS服务网络交互,获取域名对应的IP地址。
2. 浏览器再通过IP地址找到对应的IP服务器,并建立连接。浏览器发送 HTTP Request 包,服务器处理请求包,并返回 HTTP Response 包
3. 浏览器收到响应包后,绘制页面,等所有内容收到后,断开与该服务器之间的TCP连接
DNS解析
DNS是“域名系统”的英文缩写,是一种组织成域层次结构的计算机
和网络服务命名系统,它用于 TCP/IP 网络,它从事将主机名或域名转换为实际 IP 地址的工作。
DNS解析流程
上图是 DNS 解析的整个流程。
更详细的DNS即系过程如下:
- 在浏览器中输入www.qq.com域名,操作系统会先检查自己本地的hosts文件是否有这个网址映射关系,如果有,就先调用这个IP地址映射,完成域名解析。
- 如果hosts里没有这个域名的映射,则查找本地DNS解析器缓存,是否有这个网址映射关系,如果有,直接返回,完成域名解析。
- 如果hosts与本地DNS解析器缓存都没有相应的网址映射关系,首先会找TCP/IP参数中设置的首选DNS服务器,在此我们叫它本地DNS服务器,此服务器收到查询时,如果要查询的域名,包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析,此解析具有权威性。
- 如果要查询的域名,不由本地DNS服务器区域解析,但该服务器已缓存了此网址映射关系,则调用这个IP地址映射,完成域名解析,此解析不具有权威性。
- 如果本地DNS服务器本地区域文件与缓存解析都失效,则根据本地DNS服务器的设置(是否设置转发器)进行查询,如果未用转发模式,本地DNS就把请求发至13台根DNS,根DNS服务器收到请求后会判断这个域名(.com)是谁来授权管理,并会返回一个负责该顶级域名服务器的一个IP。本地DNS服务器收到IP信息后,将会联系负责.com域的这台服务器。这台负责.com域的服务器收到请求后,如果自己无法解析,它就会找一个管理.com域的下一级DNS服务器地址(qq.com)给本地DNS服务器。当本地DNS服务器收到这个地址后,就会找qq.com域服务器,重复上面的动作,进行查询,直至找到www.qq.com主机。
- 如果用的是转发模式,此DNS服务器就会把请求转发至上一级DNS服务器,由上一级服务器进行解析,上一级服务器如果不能解析,或找根DNS或把转请求转至上上级,以此循环。不管是本地DNS服务器用是是转发,还是根提示,最后都是把结果返回给本地DNS服务器,由此DNS服务器再返回给客户机。
DNS协议
阅读结合Wireshark分析DNS 协议可以对DNS协议报文有一个初步的了解;更详细的应阅读《TCP/IP详解 卷1 协议》。
HTTP协议
详细的协议阅读《HTTP权威指南》和《图解HTTP》。
############################################################
HTTP协议定义Web客户端如何从Web服务器请求Web页面,以及服务器如何把Web页面传送给客户端。HTTP协议采用了请求/响应模型。客户端向服务器发送一个请求报文,请求报文包含请求的方法、URL、协议版本、请求头部和请求数据。服务器以一个状态行作为响应,响应的内容包括协议的版本、成功或者错误代码、服务器信息、响应头部和响应数据。
以下是 HTTP 请求/响应的步骤:
1、客户端连接到Web服务器
一个HTTP客户端,通常是浏览器,与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接。例如,http://www.oakcms.cn。
2、发送HTTP请求
通过TCP套接字,客户端向Web服务器发送一个文本的请求报文,一个请求报文由请求行、请求头部、空行和请求数据4部分组成。
3、服务器接受请求并返回HTTP响应
Web服务器解析请求,定位请求资源。服务器将资源复本写到TCP套接字,由客户端读取。一个响应由状态行、响应头部、空行和响应数据4部分组成。
4、释放连接TCP连接
若connection 模式为close,则服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;若connection 模式为keepalive,则该连接会保持一段时间,在该时间内可以继续接收请求;
5、客户端浏览器解析HTML内容
客户端浏览器首先解析状态行,查看表明请求是否成功的状态代码。然后解析每一个响应头,响应头告知以下为若干字节的HTML文档和文档的字符集。客户端浏览器读取响应数据HTML,根据HTML的语法对其进行格式化,并在浏览器窗口中显示。
例如:在浏览器地址栏键入URL,按下回车之后会经历以下流程:
1、浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址;
2、解析出 IP 地址后,根据该 IP 地址和默认端口 80,和服务器建立TCP连接;
3、浏览器发出读取文件(URL 中域名后面部分对应的文件)的HTTP 请求,该请求报文作为 TCP 三次握手的第三个报文的数据发送给服务器;
4、服务器对浏览器请求作出响应,并把对应的 html 文本发送给浏览器;
5、释放 TCP连接;
6、浏览器将该 html 文本并显示内容;