一、前言
为了理解HTTP,我们有必要事先了解一下TCP/IP协议簇。
通常我们使用的网络(包括互联网)是在TCP/IP协议簇的基础上运作的。而HTTP属于它内部的一个子集。
计算机与网络设备要相互通信,双方必须基于相同的方法。比如,如何探测到通信目标、由哪一边先发起通信、使用那种语言进行通信、怎样结束通信等规则都需要事先确定。不同的硬件、操作系统之间的通信,所有的这一切都需要一种规则。而我们就把这种规则称为协议。TCP/IP是互联网相关的各类协议簇的总称。
TCP/IP协议簇最重要的一点就是分层:应用层、传输层、网络层、数据链路层。我们的HTTP就属于应用层。
HTTP协议的最新版本是3.0版本,但目前大规模使用的任然是1.1版本。
二、HTTP格式
HTTP的格式要分请求和响应两个部分来看待。
宏观上HTTP请求响应包括 报文首部、空行、报文主体(正文)
1、HTTP请求
(1)、报文首部:请求行、请求头(header)、其他
请求行: 包括方法、URL、HTTP版本
请求头:是一个个键值对的数据,键和值之间用:隔开
Host:表示服务器主机的地址和端口.
Content-Length:body数据长度(和粘包问题相关)
Content-Type:body数据格式,常见的有json,form,form-data,不同的Content-Type:服务器处理数据的逻辑不同
User-Agent:描述用啥设备上网
Referer:描述当前页面从哪一个页面跳转而来
Cookie:浏览器在本地存储数据的机制,是键值对。在一些程序过程中,会有一些数据,需要在浏览器存储,在后续请求的时候把这些数据一并发送给服务器,一般我们会想到直接把数据存到文件中,但是如果直接让网页来操纵我的电脑是非常不安全的,所有引入cookie来存储。
(2)空行:请求头结束的标记。
(3)报文主体(正文):有的http有,有的没有
HTTP的请求格式是文本格式:
2、HTTP响应
(1)、报文首部: 状态行、响应头、报文主体正文
状态行:HTTP版本、状态码、状态描述
响应头:是一个个键值对的数据,键和值之间用:隔开
Host:表示服务器主机的地址和端口.
Content-Length:body数据长度(和粘包问题相关)
Content-Type:body数据格式,例如HTML,CSS,JS,JSON,图片,字体,视频。
User-Agent:描述用啥设备上网
Referer: 描述当前页面从哪一个页面跳转而来
Cookie:浏览器在本地存储数据的机制,是键值对。在一些程序过程中,会有一些数据,需要在浏览器存储,在后续请求的时候把这些数据一并发送给服务器,一般我们会想到直接把数据存到文件中,但是如果直接让网页来操纵我的电脑是非常不安全的,所有引入cookie来存储。
(2)、空行:请求头结束的标记。
(3)、报文主体(正文):正文内容比较长,可能是多种格式,HTML,CSS,JS,JSON,图片,字体,视频等。
HTTP的响应格式是文本格式:
三、HTTPS
HTTPS是在HTTP的基础上,引入了一个加密层SSL协议。
HTTP+加密+认证+完整性保护 = HTTPS
加密可以分为 对称加密 (共享密钥加密)和 非对称加密(公开密钥加密)。
对称加密(共享密钥加密):加密和解密使用的是同一个密钥
非对称加密(公开密钥加密):加密和解密使用的是两个密钥,一把公开,一把私有。
1、加密
(1)对称加密(共享密钥加密)
对称加密客户端和服务器都是使用的相同的密钥,不同的客户端需要使用不同的密钥。那么每一个客户端连接到服务器的时候,都需要随机生成一个密钥,并把这个密钥告知给服务器(也可以是客户端生成),那么告知给对方就需要网络传输到对方,在这过程中,如果黑客拿到了密钥,后续的加密操作就毫无意义了。
出现个问题:
如果使用对称加密就始终要通过网络告诉对方密钥是什么,那么黑客始终就可以劫持。所以我们就可以使用非对称加密。
(2)非对称加密(公开密钥加密)
公开密钥加密方式很好地解决了共享密钥加密的困难。
公开密钥加密使用一对非对称的密钥。一把叫做私有密钥(private key),另一把叫做公开密钥(public key)。顾名思义,私有密钥不能让其他任何人知道,而公开密钥则可以随意发布,任何人都可以获得。
使用公开密钥加密方式,发送密文的一方使用对方的公开密钥进行加密处理,对方收到被加密的信息后,再使用自己的私有密钥进行解密。利用这种方式,不需要发送用来解密的私有密钥,也不必担心密钥被攻击者窃听而盗走。
黑客虽然知道公钥是啥,但是不知道私钥,就算拿到了加密的公钥也没办法解密。
还出现个问题:
这样对密钥和数据传输仍然还有一个巨大的问题黑客自己也可以生成公钥和私钥传给客户端,那么就会对客户端误导。
那么针对这个问题怎么解决呢?最关键的一点就是客户端拿到公钥的时候,能有办法严重是否是黑客伪造的。那么久要求服务器这边提供一个证书,证明自己是真的,没有被篡改过。
2、证书
证书中会包含一系列信息,例如服务器的域名,公钥,证书有效日期,证书是大家服务器的人要向第三方公正机构(如:威瑞信公司)申请的。
①服务器把公开密钥给认证机构
②认证机构用自己的私钥向服务器的公开密钥进行数字签名
③客户端拿到带有签名的公开密钥,使用认证机构的公开密钥进行解密(认证机构的公开密钥已事先植入到浏览器里了),以确认服务器公开密钥的真实性。
④使用服务器的公开密钥对报文加密后发送。
⑤服务器用私有密钥对报文解密
ps:证书数字签名:……(相当于校验和,把前面所有的数据通过一定的算法生成一个校验和,公证机关利用自己的私钥对校验和加密就得到签名)
当客户端收到证书以后:
1.按照同样的算法计算一个校验和1
2. 使用系统内置的公证机构公钥对证书签名解密得到校验和2
如果校验和1与校验和2相等就证明是原版的,没有被修改
如果校验和2与校验和1不相等就证明被篡改过
这样,黑客就算能修改为自己的公钥,但黑客不知道公证机关的私钥就不能对签名进行修改,那么黑客就无机可乘了。如果黑客向公证机关申请了证书,直接替换证书可以吗?那更是不可以的,证书中的服务器域名是唯一的,客户端一看就知道是假冒的。
图中图片出自《图解HTTP》,一本非常牛的书。