目录

认识请求"报头"(header)

Host

Content-Length

Content-Type

User-Agent(简称 UA)

Referer

认识“状态码“(status code)

总结

HTTPS

对称加密

非对称加密

中间人攻击

引入证书

总结


认识请求"报头"(header)

header 的整体的格式也是"键值对"结构

每个键值对占一行,键和值之间使用 “:” + “空格” 分割

键/值都是标准规定的(RFC标准文档)

Host

表示服务器主机的地址和端囗(当前的请求访问的服务器在哪里)

绝大部分情况下,Host 和 URL 中的这两个属性是一致的,但也有一些特殊场景下是不一致的

比如使用了代理,URL中的信息会被代理修改,但即使使用了代理,也可以通过 Host 来获取到最原始的目标是啥


HTTP协议中,传输时可能会涉及到“加密”(HITPS)。url 部分是不会被加密的,被加密的是header 和 body

服务器收到请求之后会做一个最终校验,验证 url 中的内容和 header 中加密的内容是否一致

Content-Length

表示body中的数据长度

HTTP协议(版本号<=2.0),传输层是基于TCP实现的

HTTP协议,就是把字符串构造成HTTP约定的格式,然后把这一串字符串写入到 tcp socket 中


对于TCP来说,一个连接上可以发多个请求,服务器收到数据的时候就需要区分一下,从哪里到哪里是一个完整的 http 请求数据

没有 body 的 http 请求,读到空行,就可以认为是结束了

有 body 的 http 请求,先读取首行和 header,读到空行,先解析 header 中的 Content-Length,根据这个值,接下来再读取固定字节的长度

Content-Type

表示请求的 body 中的数据格式,提示了接收方如何解析 body 中的数据

HTTP 携带的数据对应的格式:

HTML:text/html        浏览器会解析其中的标签,把标签转换成界面显示

CSS:text/css        浏览器会解析其中的选择器和属性,并且把这里指定的内容应用到页面的样式上

JS:application/javascript        浏览器通过js引擎解释执行js中的逻辑

JSON:application/json        浏览器不会做任何处理(在对应的 js 中进行处理)

图片:image/png 或 image/jpg        浏览器尝试按照图片的二进制格式,解析出来并显示


这些都是合法的 js 的语句,只不过使用了代码混淆(专门的工具),就能把 js 做出变换,在代码逻辑不变的情况下把 js 代码改乱,让别人读起来的成本变高

请求和响应,都会用到 Content-Length 和 Content-Type;如果有 body,并且没有这两个属性(哪怕只有一个),都认为是非法的/错误的 http 报文

User-Agent(简称 UA)

表示了用户使用的设备的浏览器和操作系统的情况

同一个时间段内,有些用户的浏览器版本是比较旧的,支持的功能少,有些用户浏览器版本更新,支持的功能多。

所以根据用户使用的设备,进行区分。通过 UA 中的浏览器版本/操作系统版本,区分出当前用户的设备,最多都支持哪些特性

老的浏览器,返回功能少的网页,正确显示;新的浏览器,返回功能多的网页,体验丰富


但是现在的浏览器,大家基本都大差不大,所以 UA 还有另外一个用途:用来区分用户的设备

windows / mac => PC

ios / android => 手机

根据用户的设备,返回不同版本的页面

^

在前端圈子中,使用 “响应式编程” 返回不同的页面

通过CSS中的 “媒体查询” 功能,感知到当前窗口的尺寸(宽度),通过不同的尺寸,设置不同的样式,一个页面,就可以适配不同的窗囗

Referer

描述了当前页面的来源,表示这个页面是从哪个页面跳转过来的

直接输入 url 或 点击收藏栏打开的页面是没有 Referer 的

cookie 就是浏览器允许网页在本地硬盘存储数据的一种机制,不是让网页代码直接访问文件系统,而是做了一层抽象(浏览器的 cookie 提供了键值对存储机制)

浏览器中可以直接看到当前页面保存的cookie有哪些,浏览器保存了这些cookie之后,就会在后续给服务器发送请求的时候,把这些cookie键值对放到请求cookie header中传输给服务器

定义:Cookie 是服务器发送到用户浏览器并保存在本地的一小块数据

工作原理:

1. 用户访问网站,服务器创建 Cookie 并将其发送给浏览器。

2. 浏览器将 Cookie 保存在本地。

3. 用户再次访问该网站时,浏览器将 Cookie 发送回服务器。

4. 服务器读取 Cookie 信息,识别用户或获取相关数据

Cookie 到哪里去:最终发回给服务器,后续给服务器发的请求,都会带上Cookie

Cookie 从哪里来:也是从服务器来的,是通过 Set-Cookie 返回的(Cookie 里有哪些键值对,是后端开发程序员决定的)

存储方式:按照域名为维度,以键值对的方式来存储

作用:Cookie 中的内容都是程序员自定义的,可以根据需要存储不同的内容。最典型的场景:实现登录身份认证

详细可看这个文档:https://cloud.tencent.com/developer/article/2561291

认识“状态码“(status code)

状态码位于 HTTP 响应的首行中,表示响应的结果(是访问成功,还是失败,还是其他的一些情况)

常见的状态码:

200 OK:这是一个最常见的状态码,表示访问成功

404 Not Found:访问的资源没有找到

浏览器输入一个URL,目的就是为了访问对方服务器上的一个资源,如果这个URL标识的资源不存在,那么就会出现404

例如,在浏览器中输入 www.sogou.com/index.html,此时就在尝试访问sogou上的 /index.html 这个资源,如果输入正确,则可以正确访问到,但是如果输入错误,比如www.sogou.com/index2.html,就会看到404这样的响应

状态码即使是404,也可以在 body 中返回一些 html之类的,把这个404页面弄的漂亮一些

403 Forbidden:表示访问被拒绝

有的页面通常需要用户具有一定的权限才能访问(登陆后才能访问),如果用户没有登陆直接访问,就容易见到 403

405 Method Not Allowed

前面说过了 HTTP 中所支持的方法,有 GET,POST,PUT,DELETE 等,但是对方的服务器不一定都支持所有的方法(或者不允许用户使用一些其他的方法)

500 Internal Server Error

服务器出现内部错误。一般是服务器的代码执行过程中遇到了一些特殊情况(比如服务器处理逻辑的代码中抛出异常,但是没有catch到)会产生这个状态码。平时常用的网站很少会出现500(但是偶尔也能看到)

504 Gateway Timeout

当服务器负载比较大的时候,服务器处理单条请求的时候消耗的时间就会很长,就可能会导致出现超时的情况。这种情况在选课系统中容易出现

302 Move temporarily:重定向

在登陆页面中经常会见到302,用于实现登陆成功后自动跳转到主页

总结

2xx 都是成功

3xx 都是重定向

4xx 是客户端出错(用户构造的请求有问题)

5xx 服务器出错

HTTPS

HTTPS = HTTP + S (SSL / TLS)

HTTPS 也是一个应用层协议,是在 HTTP 协议的基础上引入了一个加密层。

HTTP 协议内容都是按照文本的方式明文传输的,这就导致在传输过程中出现一些被篡改的情况。由于我们通过网络传输的任何的数据包都会经过运营商的网络设备(路由器,交换机等),那么运营商的网络设备就可以解析出你传输的数据内容,并进行篡改

HTTPS就是在HTTP的基础上进行了加密,进一步的来保证用户的信息安全

HTTPS的工作过程:

既然要保证数据安全,就需要进行 "加密"。网络传输中不再直接传输明文了,而是加密之后的 “密文"

加密的方式有很多,但是整体可以分成两大类:对称加密和非对称加密

对称加密

对称加密其实就是通过同一个“密钥”,把明文加密成密文,并且也能把密文解密成明文

需要在客户端和服务器建立连接的时候,双方协商确定这次的密钥是啥。但是如果直接把密钥明文传输,那么黑客也就能获得密钥了,后续的加密操作就形同虚设了

因此密钥的传输也必须加密传输,但是要想对密钥进行对称加密,就仍然需要先协商确定一个“密钥的密钥”,所以密钥的传输再用对称加密就行不通了,就需要引入非对称加密

非对称加密

非对称加密要用到两个密钥,一个叫做“公钥”,一个叫做“私钥”

公钥和私钥是配对的,最大的缺点就是运算速度非常慢,比对称加密要慢很多

  • 通过公钥对明文加密,变成密文
  • 通过私钥对密文解密,变成明文

也可以反着用

  • 通过私钥对明文加密,变成密文
  • 通过公钥对密文解密,变成明文

1. 客户端在本地生成对称密钥,通过公钥加密,发送给服务器

2. 由于中间的网络设备没有私钥,即使截获了数据,也无法还原出内部的原文,也就无法获取到对称密钥

3. 服务器通过私钥解密,还原出客户端发送的对称密钥,并且使用这个对称密钥加密给客户端返回的响应数据

4. 后续客户端和服务器的通信都只用对称加密即可。由于该密钥只有客户端和服务器两个主机知道,其他主机/设备不知道密钥即使截获数据也没有意义

由于对称加密的效率比非对称加密高很多,因此只是在开始阶段协商密钥的时候使用非对称加密,后续的传输仍然使用对称加密

问题又来了:客户端如何获取到公钥? 如何确定获取到的这个公钥不是黑客伪造的?

中间人攻击

黑客可以使用中间人攻击,获取到对称密钥

1. 服务器具有非对称加密算法的公钥S,私钥S'

2. 中间人具有非对称加密算法的公钥M,私钥M'

3. 客户端向服务器发起请求,服务器明文传送公钥S给客户端

4. 中间人劫持数据报文,提取公钥S并保存好,然后将被劫持报文中的公钥S替换成为自己的公钥M,并将伪造报文发给客户端

5. 客户端收到报文,提取公钥M(自己当然不知道公钥被更换过了),自己形成对称秘钥X,用公钥M加密X,形成报文发送给服务器

6. 中间人劫持后,直接用自己的私钥M'进行解密,得到通信秘钥X,再用曾经保存的服务端公钥S加密后,将报文推送给服务器

7. 服务器拿到报文,用自己的私钥S'解密,得到通信秘钥X

8. 双方开始采用X进行对称加密,进行通信。但是一切都在中间人的掌握中,劫持数据,进行窃听甚至修改,都是可以的

引入证书

中间人攻击的关键,在于客户端无法区分收到的公钥是否是服务器真实的公钥还是被黑客篡改的公钥。想办法能够对公钥是否正确,进行校验。引入证书就可以对公钥进行校验

服务端在使用 HTTPS 前,需要向公证机构(CA机构)申领一份数字证书,数字证书里含有证书申请者信息、公钥信息等。服务器把证书传输给浏览器,浏览器从证书里获取公钥就行了,证书就如身份证,证明服务端公钥的权威性

这个证书可以理解成是一个结构化的字符串,里面包含了以下信息:

证书发布机构、证书有效期、服务器公钥、服务器的拥有者(域名)、证书的数字签名等。其中除了数字签名,其他的是证书明文部分

数字签名是如何获得的:

1. 把证书明文 (包含公钥) 作为输入,代入一个固定的公式,生成校验和

2. 对校验和进行加密(第三方认证机构,也生成一对非对称密钥)

证书明文和数字签名共同组成了数字证书,这样一份数字证书就可以颁发给服务端了

通过证书解决中间人攻击

在客户端和服务器刚一建立连接的时候,服务器给客户端返回一个证书

这个证书包含了公钥,也包含了网站的身份信息

当客户端获取到这个证书之后,会对证书进行校验(防止证书是伪造的)

1. 判定证书的有效期是否过期

2. 判定证书的发布机构是否受信任(操作系统中已内置的受信任的证书发布机构)

3. 验证证书是否被篡改

1)客服端对证书中的明文信息使用同样的计算公式,再算一次校验和,得到了校验和1

2)再通过公正机构的公钥对数字签名进行解密,得到校验和2

系统中内置了一系列知名公正机构的公钥,不是通过网络传输的

3)对比校验和1和校验和2是否相同,如果相同,说明证书是没有被修改过的

总结

HTTPS工作过程中涉及到的密钥有三组

第一组(非对称加密):用于校验证书是否被篡改。服务器持有私钥(私钥在注册证书时获得),客户端持有公钥(操作系统包含了可信任的CA认证机构有哪些,同时持有对应的公钥),服务器使用这个私钥对证书的签名进行加密,客户端通过这个公钥解密获取到证书的签名,从而校验证书内容是否是篡改过

第二组(非对称加密):用于协商生成对称加密的密钥。服务器生成这组私钥-公钥对,然后通过证书把公钥传递给客户端,然后客户端用这个公钥给生成的对称加密的密钥加密,传输给服务器,服务器通过私钥解密获取到对称加密密钥

第三组(对称加密):客户端和服务器后续传输的数据都通过这个对称密钥加密解密

第二组非对称加密的密钥是为了让客户端把这个对称密钥传给服务器

第一组非对称加密的密钥是为了让客户端拿到第二组非对称加密的公钥

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐