C++ HTTP 协议

概念

http 就是 通过 http 协议 在服务器上 拿下来对应资源

在网络中看到的都是资源,在服务器资源上文件种类很多 所以需要系统文件路径

HTTP 超文本传输协议 URL 域名

urlencode 和 urldecode

http协议格式

http request

GET url http version |-- 请求行

------------------
name: value\r\n
name: value\r\n
name: value\r\n
name: value\r\n
name: value\r\n
name: value\r\n
-----------------
🤓☝️  : 请求报头

\r\n |------空行

请求正文:(可以没有)
-------------------
username=""&password=""
-------------------

http response

http/1.1 状态码 状态码描述\r\n |--- 状态行

------------------
name: value\r\n
name: value\r\n
name: value\r\n
name: value\r\n
name: value\r\n
name: value\r\n
-----------------
🤓☝️  : 响应报头

\r\n | -------------- 空行

响应正文:
----------------------
html/css/图片/视频/音频。。。。
----------------------

  • 请求和响应怎么保证应用层完整读取完毕呢?

    • 我可以读取完整的一行

    • while 读取完整的一行 - 所有的请求行+请求报头全部读完-直到空行!

    • 可以保证吧报头读完,报头的属性 Content-Length: xxx正文长度

    • 根据内容长度 读取正文即可

  • 请求和响应怎么保证序列化和反序列化的?

    • http 自己实现的,第一行+请求/响应报头 按照\r\n 将字符串1->n 即可

HTTP 请求方法

HTTP定义了几种请求方法,最常见的是:

  1. GET: 用于从服务器获取资源。GET请求通常不包含请求体(Body),数据通过URL参数传递。

  2. POST: 用于向服务器提交数据,通常用于表单提交或上传文件。POST请求包含请求体(Body),数据在Body中传递。

HTTP 请求结构

一个HTTP请求通常由以下几部分组成:

  1. 首行: 包含请求方法、URL和HTTP版本。

    • 示例: GET /index.html HTTP/1.1

  2. Header: 请求的属性,以键值对的形式表示,每组属性之间使用换行符(\n)分隔。遇到空行表示Header部分结束。

    • 示例:

      Host: www.example.com
      User-Agent: Mozilla/5.0
      Content-Type: application/x-www-form-urlencoded
      Content-Length: 16
  3. Body: 空行后面的内容是Body。Body允许为空字符串。如果Body存在,Header中会有一个Content-Length属性来标识Body的长度。

    • 示例: name=John&age=30

HTTP 响应结构

一个HTTP响应通常由以下几部分组成:

  1. 首行: 包含HTTP版本、状态码和状态码解释。

    • 示例: HTTP/1.1 200 OK

  2. Header: 响应的属性,以键值对的形式表示,每组属性之间使用换行符(\n)分隔。遇到空行表示Header部分结束。

    • 示例:

      Content-Type: text/html; charset=UTF-8
      Content-Length: 1234
      Server: Apache/2.4.1 (Unix)
  3. Body: 空行后面的内容是Body。Body允许为空字符串。如果Body存在,Header中会有一个Content-Length属性来标识Body的长度。如果服务器返回了一个HTML页面,那么HTML页面内容就在Body中。

    • 示例: <html><body>Hello, World!</body></html>

常见的HTTP Header

  • Content-Type: 标识请求或响应中Body的数据类型(如text/html, application/json等)。

  • Content-Length: 标识Body的长度(字节数)。

  • Host: 客户端告知服务器,所请求的资源是在哪个主机和端口上。

  • User-Agent: 声明用户的操作系统和浏览器版本信息。

  • Referer: 当前页面是从哪个页面跳转过来的。

  • Location: 搭配3xx状态码使用,告诉客户端接下来要去哪里访问(通常用于重定向)。

  • Cookie: 用于在客户端存储少量信息,通常用于实现会话(session)的功能。

HTTP 响应码

  • 1xx(信息性状态码):表示接收的请求正在处理。

  • 2xx(成功状态码):表示请求正常处理完毕。

  • 3xx(重定向状态码):需要后续操作才能完成这一请求。

  • 4xx(客户端错误状态码):表示请求包含语法错误或无法完成。

  • 5xx(服务器错误状态码):服务器在处理请求的过程中发生了错误。

3XX 重定向

返回响应码为 3xx 并且附带一个地址时,将会直接重定向到该目标地址。

临时重定向(HTTP状态码 302 或 307)和永久重定向(HTTP状态码 301)

  • 临时重定向:表示资源临时移动,客户端应继续使用原有 URI。

  • 永久重定向:表示资源永久移动,客户端应使用新的 URI。

长连接的概念

HTTP 是基于 TCP 的协议,默认情况下每次请求都会创建一个新的连接,这会导致频繁的连接创建和关闭。长连接通过保持连接打开来解决这个问题,从而减少连接建立的开销。

  • 长连接:通过 Connection: keep-alive 头部字段来实现,允许在同一个连接上发送多个请求和响应。

HTTP 会话保持

HTTP 是无状态协议,但用户需要会话保持来识别用户身份和状态。

  • 会话保持:通过 Cookie 和 Session 实现。

    • Cookie:浏览器保存用户信息并在每次请求时发送给服务器。

    • Session:服务器端保存用户信息,通过 Session ID 识别用户。

在响应头中设置 Set-Cookie 字段来写入 Cookie 信息:

Set-Cookie: value\r\n

HTTPS

HTTP 是明文传输的,而 HTTPS 是通过 TLS/SSL 加密的。

  • HTTP:默认使用 80 端口。

  • HTTPS:默认使用 443 端口。

常见加密算法

对称加密

  • 定义:使用同一个密钥进行加密和解密。

  • 常见算法:DES、3DES、AES、TDEA、Blowfish、RC2 等。

  • 特点:算法公开、计算量小、加密速度快、效率高。

非对称加密

  • 定义:使用一对密钥(公钥和私钥)进行加密和解密。

  • 常见算法:RSA、DSA、ECDSA 等。

  • 特点:算法复杂、安全性高,但加密解密速度较慢。

加密的安全性

  • 算力成本:加密的安全性依赖于算法的复杂度和密钥的长度,破解加密需要大量的计算资源。

HTTPS 的工作过程

HTTPS(HyperText Transfer Protocol Secure)是通过在 HTTP 上添加 SSL/TLS 层来实现安全通信的协议。它主要解决了数据被监听和篡改的问题。以下是 HTTPS 的详细工作过程:

数据摘要和数据指纹

Hash 摘要:将任意长度的输入通过哈希函数转换成固定长度的输出。哈希算法是不可逆的,即无法从哈希值还原原始数据。

对称加密和非对称加密

对称加密:使用相同的密钥进行加密和解密。虽然对称加密速度快,但密钥的安全传输是个问题。

非对称加密:使用一对密钥(公钥和私钥)进行加密和解密。公钥加密的数据只能用对应的私钥解密,反之亦然。非对称加密解决了密钥传输的问题,但速度较慢。

HTTPS 的混合加密机制

HTTPS 结合了对称加密和非对称加密的优点:

服务端生成非对称密钥对:公钥 S 和私钥 S'。

客户端发起 HTTPS 请求:获取服务端的公钥 S。

客户端生成对称密钥 C:用公钥 S 加密后发送给服务器。

服务器用私钥 S' 解密:获取对称密钥 C。

后续通信使用对称加密:客户端和服务器使用对称密钥 C 进行加密和解密。

中间人攻击的防范

中间人攻击:中间人试图拦截和篡改通信内容。

服务器发送公钥 S:中间人拦截并替换为自己的公钥 M。

客户端用公钥 M 加密对称密钥 X:发送给服务器。

中间人解密并重新加密:用自己的私钥 M 解密,再用服务器的公钥 S 加密,发送给服务器。

服务器解密并使用对称密钥 X:进行通信。

虽然中间人可以解密和篡改通信内容,但 HTTPS 通过证书验证机制防止这种攻击。

证书验证

CA 证书:由可信的证书颁发机构(CA)签发,包含公钥、域名、有效期等信息。

证书签名:CA 用自己的私钥对证书信息进行签名,生成数字签名。

客户端验证证书:用 CA 的公钥解密数字签名,验证证书的合法性。

CA 证书

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

CA证书申请流程

当服务端申请CA证书时,CA机构会对该服务端进行审核,并专门为该网站形成数字签名。具体过程如下:

  1. CA机构拥有非对称加密的私钥A和公钥A

  2. CA机构对服务端申请的证书明文数据进行hash,形成数据摘要

  3. 对数据摘要用CA私钥A加密,得到数字签名S

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

证书签名过程

  • 证书签名Sig = Enc_by_private_CA[Hash(INFO)]

  • 审核信息

    • 签发机构:CA_qq

    • 有效时间:2022/1/1-2024/1/1

    • 扩展信息:...

    • 域名:cdn.qq.com

    • 申请者:TEG/APD

    • 公钥:pub_server

证书验证过程

  1. 申请认证:生成公钥与私钥对(pub_svr & pri_svr),计算明文信息INFO的摘要(D_cal = Hash(INFO)),生成请求文件.csr。

  2. 签发证书:用CA证书的公钥解密签名,确认申请信息(D_pem = Dec_by_pub_CA[Sig]),对比两个摘要(D_cal == D_pem)。

  3. 验证证书:验证域名、有效时间、是否吊销等信息。

  4. 返回证书:客户端收到证书后进行验证。

  5. 密钥协商:客户端和服务器进行密钥协商。

理解数据签名

  • 签名:用签名者的私钥加密散列值,生成数字签名。

  • 验证:用签名者的公钥解密散列值,比较解密后的散列值与原始数据的散列值是否一致。

中间人攻击的防范

  • 篡改证书:中间人无法篡改证书的明文,因为没有CA机构的私钥,无法生成匹配的签名。

  • 掉包证书:中间人无法制作假的证书,只能申请真证书进行掉包,但客户端可以通过证书明文中的域名等信息识别出掉包行为。

HTTPS工作过程

HTTPS中CA证书的签发及使用过程 - xdyixia - 博客园