应用层协议HTTP
应用层协议是可以由程序员自己制定的,但是自己写的协议没有统一标准,只有协议设计者自己的系统能识别。
我们日常接触的绝大多数应用层协议,都由权威标准化组织发布,目的是保证不同厂商、不同系统之间的互通性。
HTTP协议的概念
HTTP (HyperText Transfer Protocol,超文本传输协议)是TCP/IP 协议簇中的应用层协议,专门用于客户端与服务器之间的超文本数据传输,
- HTTP基于请求-响应模型:浏览器像服务器发起请求,就是通过 HTTP 来完成的 ------ 客户端发送请求,服务器返回响应,以此实现网页、图片、视频等资源的获取。
HTTP协议是⼀个⽆连接、⽆状态的协议
- 无连接:客户端和服务器之间的 TCP 连接是 一次性 的,每次请求一个资源,就建立一次 TCP 连接,请求完成后立即断开。(现在的优化HTTP/1.1和它之后的HTTP协议:引入了
Keep-Alive(持久连接),默认是 长连接)。 - 无状态:HTTP 协议本身不存储客户端的请求历史,服务器每次处理请求时,都把它当成一个 "全新的、独立的请求",和之前的请求没有任何关联。
认识URL
URL就是我们平时所说的网址,是因特网的万维网服务程序上用于指定信息位置的表示方法。

协议方案和域名
上面有很多东西都是可以选择不填的,但要访问一个网址至少是需要协议方案和域名。
- 协议方案名:就是服务器所使用协议,我们平常所见到的就是HTTP协议或安全协议HTTPS。HTTPS是以安全为目标的HTTP通道,在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性。
- **HTTP:**明文传输
- **HTTPS:**加密传输
- 域名:事实上,的确在技术上用ip地址和端口号就可以实现这样的功能,但是在日常生活中作为用户会直接使用一个域名的内容来进行访问网站,因为域名的名字相比起来更加的好记忆,所以就会转化成用户能够认出的名称。比如通过拼音baidu我们大概就能知道这是百度服务器下的内容。其实除了IP,还有一个应该是端口号,可是这里没有,因为端口号是知道的(默认端口: HTTP为
80,HTTPS为443。),所以一般不会显示地写在URL中。
域名实际上在背后会被解析为对应的服务,这个技术上叫做是域名解析,域名解析的核心就是将人类易记的域名转换为机器能识别的 IP 地址。
我们通过如下命令来查看

带层次的文件路径
/dir/index.htm表示的是要访问的资源所在的路径。访问服务器的目的是获取服务器上的某种资源,通过前面的域名和端口已经能够找到对应的服务器进程了,此时要做的就是指明该资源所在的路径。
下图表示了qq,com根目录下的search目录:

查询字符串
URL 里的查询字符串,是跟在?后面的部分,作用是向服务器传递额外的参数信息,格式是key=value,多个参数用&分隔。
比如腾讯网上面搜索舌尖上的中国,此时可以看到URL中有很多参数,而在这众多的参数当中有一个参数 查询( query),表示的就是我们搜索时的搜索关键字query=舌尖上的中国。并且通过&符号分隔开的,page=1,代表这是第一页。

片段标识符
URL 里的片段标识符 (也叫 "锚点")是跟在#后面的部分,核心作用是在客户端定位到页面内的具体位置,全程不会发送到服务器。
urlencode和urldecode
像 / ? : 等这样的字符, 已经被 url 当做特殊意义理解了. 因此这些字符不能随意出现.
转义的规则如下:
- 将需要转码的字符转为16进制,然后从右到左,取4位(不⾜4位直接处理),每2位做⼀位,前⾯加上%,编码成%XY格式
倘若某个参数中需要带有这些特殊字符, 就必须先对特殊字符进⾏转义.
例如图中%2B代表了+,%2F代表了/ .

HTTP协议请求
请求协议格式
HTTP 协议规定,请求从客户端发出,最后服务器端响应该请求并返回。换句话说,肯定是先从客户端开始建立通信的,服务器端在没有接收到请求之前不会发送响应。
HTTP请求协议格式如下:

HTTP请求由以下四部分组成:
- 请求行:请求方法 + 资源路径 + 协议版本
- 请求报头(Header):请求的属性, 冒号分割的键值对;每组属性之间使⽤ \r\n 分隔;遇到空⾏表⽰ Header部分结束
- 空行:遇到空行表示请求报头结束
- Body: 空⾏后⾯的内容都是Body. Body允许为空字符串. 如果Body存在, 则在Header中会有⼀个Content-Length属性来标识Body的⻓度;
响应协议格式


HTTP响应由以下四部分组成:
- ⾸⾏: [版本号] + [状态码] + [状态码解释]
- 请求报头(Header): 请求的属性, 冒号分割的键值对;每组属性之间使⽤\r\n分隔;遇到空⾏表⽰Header部分结束
- 空行:遇到空行表示请求报头结束
- Body: 空⾏后⾯的内容都是Body. Body允许为空字符串. 如果Body存在, 则在Header中会有⼀个Content-Length属性来标识Body的⻓度; 如果服务器返回了⼀个html⻚⾯, 那么html⻚⾯内容就是在body中.
HTTP协议请求方法
HTTP常见的方法如下

GET方法
-
核心功能 :客户端通过
GET方法向服务器请求指定资源(如 HTML 文件、图片、数据等)。 -
参数传递 :请求参数通常附加在 URL 的查询字符串 中(如
/page?name=Alice&age=20)。
POST 方法
- 数据提交:不像 GET 方法把参数拼在 URL 里,POST 的参数是放在正文中的,没有严格的长度限制,更适合传递敏感 / 大量数据。
- 非幂等操作 :"幂等性" 是指 "多次请求的结果是否一致",多次相同的 POST 请求可能导致不同结果(如重复提交订单会创建多个记录)。
HTTP的状态码

1xx(信息性状态码)
-
**100 Continue:**客户端应继续发送请求正文(用于大文件上传前的确认)
-
**101 Switching Protocols:**服务器同意切换协议(如从 HTTP 升级到 WebSocket)
2xx 成功类
- 200 OK:最常见的成功状态,服务器已返回请求的资源(比如网页、接口数据)。
- 201 Created :请求成功且创建了新资源(比如提交表单后生成了新用户)。
- 204 No Content :请求成功,但没有返回内容(比如删除操作成功后,仅返回状态码)。
3xx 重定向类
- 301 Moved Permanently :永久重定向(比如旧域名跳转到新域名,搜索引擎会更新索引)。
- 302 Found :临时重定向(比如活动页面临时跳转到首页,搜索引擎不会更新索引)。
- 304 Not Modified :资源没有被修改,客户端直接用本地缓存(减少服务器压力)。
4xx 客户端错误类
- 400 Bad Request:请求格式错误(比如参数不合法、JSON 格式错误)。
- 403 Forbidden:服务器拒绝请求(比如没有权限访问某个页面)。
- 404 Not Found:请求的资源不存在(比如输错了 URL)。
- 405 Method Not Allowed:请求方法不被允许(比如用 POST 访问只支持 GET 的接口)。
5xx 服务器错误类
- 500 Internal Server Error:服务器内部出错(比如代码 bug、数据库连接失败)。
- 502 Bad Gateway:服务器作为 "网关",收到了上游服务器的无效响应(比如反向代理后面的服务挂了)。
- 503 Service Unavailable:服务器暂时不可用(比如服务器过载、维护中)。
HTTP常⻅Header
请求 Header(客户端 → 服务器)
以下是几个常见的:
- Content-Type: 数据类型(text/html等)
- Content-Length: Body的⻓度
- Host: 客⼾端告知服务器, 所请求的资源是在哪个主机的哪个端⼝上;
- User-Agent: 声明⽤⼾的操作系统和浏览器版本信息;
- Referer: 当前⻚⾯是从哪个⻚⾯跳转过来的;
- Location: 搭配3xx状态码使⽤, 告诉客⼾端接下来要去哪⾥访问;
- Cookie: ⽤于在客⼾端存储少量信息.
手写HttpServer
HTTPS协议原理
HTTP 是明文传输,数据在网络中传输时,黑客可以轻易监听、篡改或伪造(即中间人攻击)
HTTPS 也是⼀个应⽤层协议. 是在 HTTP 协议的基础上引⼊了⼀个加密层。HTTPS 的全称是 HyperText Transfer Protocol Secure ,即超文本传输安全协议 ,本质是 HTTP + SSL/TLS 的组合,在 HTTP 的基础上,通过 SSL/TLS 协议对传输的数据进行加密 和身份验证,解决了 HTTP 明文传输的安全隐患。
什么是"加密"
加密 是一种信息安全技术 ,核心是通过特定的算法和密钥 ,将明文 转换成密文 (杂乱无章的乱码),只有拥有正确密钥的接收方,才能把密文还原成明文。
在这个加密和解密的过程中, 往往需要⼀个或者多个中间的数据, 辅助进⾏这个过程, 这样的数据称为 密钥。
为什么要加密
中间人攻击
这是传输层窃取的核心手段,也是 HTTP 明文传输的致命缺陷,攻击流程如下:
劫持链路:攻击者通过局域网 ARP 欺骗、公共 WiFi 钓鱼、路由器漏洞等方式,插入到客户端和服务器之间的通信链路中。
- 转发数据:客户端发往服务器的请求会先到攻击者设备,攻击者转发给服务器;服务器的响应也会先到攻击者,再转发给客户端。
- 明文窃取:如果是 HTTP 请求,数据是明文的,攻击者可以直接读取请求头、请求体里的账号、密码、Cookie 等信息。
- HTTPS 的绕过情况:如果客户端验证证书不严格(比如信任自签名证书),攻击者可以伪造服务器证书,让客户端误以为是合法服务器,从而解密 HTTPS 数据。
常见加密方式
加密技术主要分为 对称加密 、非对称加密 两大类。
另外还有 数据摘要/数据指纹( 不属于 "加密"(因为无法解密),而是将任意长度的数据转换为 固定长度的哈希值),三者在不同场景下搭配使用。
对称加密
- 采⽤单钥密码系统的加密⽅法,同⼀个密钥可以同时⽤作信息的加密和解密,这种加密⽅法称为对称加密,也称为单密钥加密,特征:加密和解密所⽤的密钥是相同的。
- 特点:算法公开、计算量⼩、加密速度快、加密效率⾼。
对称加密其实就是通过同⼀个 "密钥" , 把明⽂加密成密⽂, 并且也能把密⽂解密成明⽂.
- ⼀个简单的对称加密, 按位异或假设 明⽂ a = 1234, 密钥 key = 8888 则加密 a ^ key 得到的密⽂ b 为 9834.然后针对密⽂ 9834 再次进⾏运算 b ^ key, 得到的就是原来的明⽂ 1234. (对于字符串的对称加密也是同理, 每⼀个字符都可以表⽰成⼀个数字) 当然, 按位异或只是最简单的对称加密. HTTPS 中并不是使⽤按位异或.
⾮对称加密
- 非对称加密 核心特征是加密和解密使用一对不相同但配对的密钥 ------公钥 和私钥,两者是数学上关联的,且无法从其中一个推导出另一个。
- 特点:算法强度复杂、安全性依赖于算法与密钥但是由于其算法复杂,⽽使得加密解密速度没有对称加密解密的速度快。
公钥和私钥是配对的. 最⼤的缺点就是运算速度⾮常慢,⽐对称加密要慢很多.
- 通过公钥对明⽂加密, 变成密⽂
- 通过私钥对密⽂解密, 变成明⽂
也可以反着⽤
- 通过私钥对明⽂加密, 变成密⽂
- 通过公钥对密⽂解密, 变成明⽂
⾮对称加密的数学原理⽐较复杂, 涉及到⼀些 数论 相关的知识. 这⾥举⼀个简单的⽣活上的例⼦. A 要给 B ⼀些重要的⽂件, 但是 B 可能不在. 于是 A 和 B 提前做出约定:B 说: 我桌⼦上有个盒⼦, 然后我给你⼀把锁, 你把⽂件放盒⼦⾥⽤锁锁上, 然后我回头拿着钥匙来开锁取⽂件.在这个场景中, 这把锁就相当于公钥, 钥匙就是私钥. 公钥给谁都⾏(不怕泄露), 但是私钥只有 B ⾃⼰持有. 持有私钥的⼈才能解密.
数据摘要 && 数据指纹
- 数字指纹(数据摘要),其基本原理是利⽤单向散列函数(Hash函数)对信息进⾏运算,⽣成⼀串固定⻓度的数字摘要。数字指纹并不是⼀种加密机制,但可以⽤来判断数据有没有被篡改。
- 摘要常⻅算法:有MD5、SHA1、SHA256、SHA512等,算法把⽆限的映射成有限,因此可能会有碰撞(两个不同的信息,算出的摘要相同,但是概率⾮常低)
- 摘要特征:和加密算法的区别是,摘要严格意义不是加密,因为没有解密,只不过从摘要很难反推原信息,通常⽤来进⾏数据对⽐。
数字摘要主要解决的是数据有没有被篡改的问题。
网络传输校验:数据在传输中可能被劫持篡改,发送方会附带数据的哈希值,接收方验证哈希值,就能判断数据是否完整。
HTTPS 的⼯作过程探究
只使⽤对称加密
很明显在客服端和服务端之间发送密钥的时候,中间人就可能把密钥窃走了。所以只使⽤对称加密是不安全的。

只使用非对称加密
第二种方法是可以使用非对称的加密方式,具体原理可以看做是,服务器先把公钥传输给浏览器,之后浏览器向服务器传输数据之前都使用公钥加密好再传递给服务器,服务器使用私钥解开公钥加密的数据。
看着好像有点靠谱,但是服务器到浏览器的这条路怎么保障安全?
- 如果服务器⽤它的私钥加密数据传给浏览器,那么浏览器⽤公钥可以解密它,⽽这个公钥是⼀开始通过明⽂传输给浏览器的,若这个公钥被中间⼈劫持到了,那他也能⽤该公钥解密服务器传来的信息了。
双⽅都使⽤⾮对称加密
交换完公钥之后双方都用对方的公钥进行加密,在用自己的密钥进行解密。
看似是可行的,实则效率低下,并且也能够被破解,现在我作为中间人我要开始攻击了:

在客户端服务端毫不知情的情况下,窃取了他们的数据。
非对称加密+对称加密
该方法解决了效率问题,但还是一样的会被攻击所以也是不行的。

数字签名

数字签名的过程:
- 创建消息摘要:发送者使用哈希函数(如SHA-256)生成消息的摘要,这是一个固定长度的字符串,代表了原始消息的内容。
- 使用私钥进行加密:发送者使用自己的私钥对消息摘要进行加密,生成数字签名。
- 发送消息和签名:发送者将原始消息和数字签名一起发送给接收者。
- 验证签名:接收者使用发送者的公钥对数字签名进行解密,得到消息摘要。
- 验证消息摘要:接收者生成接收到的消息的摘要。
- 比较摘要:接收者比较接收到的摘要和用发送者公钥解密得到的摘要。如果两者相同,说明消息未被篡改。
非对称加密+对称加密+数字签名
倘若使用"非对称加密+对称加密+数字签名",还是不安全的
假设你是客户端,想和服务器安全通信,你设计的步骤是:
服务器生成一对非对称密钥(
Pub_S公钥、Pri_S私钥);服务器用自己的
Pri_S对Pub_S做数字签名,得到Sign_S;服务器把
Pub_S + Sign_S一起发给你;你收到后,用
Pub_S验证Sign_S------ 如果验证通过,就认为Pub_S是真的;你生成对称密钥,用
Pub_S加密后发给服务器,后续用对称密钥通信。
中间人只需要做 3 步,就能彻底攻破这个验证逻辑:中间人拦截 :截获服务器发给你的
Pub_S + Sign_S;中间人伪造 :
- 生成自己的密钥对
Pub_M + Pri_M;- 用
Pri_M对Pub_M做签名,得到Sign_M;- 把
Pub_M + Sign_M冒充成服务器的消息,发给你;
所以还是不行的。
CA证书 + 数字签名
那为了解决这个问题,因此引入了证书的概念,服务端在使⽤HTTPS前,需要向CA机构申领⼀份数字证书,数字证书⾥含有证书申请者信息、公钥信息等。服务器把证书传输给浏览器,浏览器从证书⾥获取公钥就⾏了,证书就如⾝份证,证明服务端公钥的权威性

⾮对称加密 + 对称加密 + 证书认证
在客⼾端和服务器刚⼀建⽴连接的时候, 服务器给客⼾端返回⼀个 证书,证书包含了之前服务端的公钥, 也包含了⽹站的⾝份信息.
客⼾端进⾏认证:
- 当客⼾端获取到这个证书之后, 会对证书进⾏校验(防⽌证书是伪造的).
- 判定证书的有效期是否过期
- 判定证书的发布机构是否受信任(操作系统中已内置的受信任的证书发布机构).
- 验证证书是否被篡改: 从系统中拿到该证书发布机构的公钥, 对签名解密, 得到⼀个 hash 值(称为数据摘要), 设为 hash1. 然后计算整个证书的 hash 值, 设为 hash2. 对⽐ hash1 和 hash2 是否相等. 如果相等, 则说明证书是没有被篡改过的.
中间⼈有没有可能篡改该证书?
- 中间⼈篡改了证书的明⽂
- 由于他没有CA机构的私钥,所以⽆法hash之后⽤私钥加密形成签名,那么也就没法办法对篡改后的证书形成匹配的签名
- 如果强⾏篡改,客⼾端收到该证书后会发现明⽂和签名解密后的值不⼀致,则说明证书已被篡改,证书不可信,从⽽终⽌向服务器传输信息,防⽌信息泄露给中间⼈
在这前非对称加密+对称加密+数字签名方案时,中间人会掉包数字签名和公钥。
中间⼈有没有可能整个掉包证书?
- 因为中间⼈没有CA私钥,所以⽆法制作假的证书
- 所以中间⼈只能向CA申请真证书,然后⽤⾃⼰申请的证书进⾏掉包
- 这个确实能做到证书的整体掉包,但是别忘记,证书明⽂中包含了域名等服务端认证信息,如果整体掉包,客⼾端依旧能够识别出来。
- 所以中间⼈没有CA私钥,所以对任何证书都⽆法进⾏合法修改,包括证书申请者⾃⼰。
HTTPS 的本质
最后HTTPS 的本质就是 「数字证书 + 非对称加密 + 对称加密」三者的有机结合,三者各司其职、缺一不可,共同构建了安全的通信链路。

