应用层http协议包解析与https加密策略解析

在这里插入图片描述

文章目录

  • 一.应用层协议--http协议基础认知
  • 二.https协议加密策略解析
    • 加密策略1--通信双方只使用对称加密
    • 加密策略2--通信双方使用单方非对称加密
    • 加密策略3--通信双方都使用非对称加密
    • 加密策略4--非对称加密与对称加密配合使用
    • 中间人攻击
    • 数据签名与CA证书
    • HTTPS数据安全认证的本质:非对称加密+对称加密+证书认证

一.应用层协议–http协议基础认知

  • 图解http协议报文结构:
    在这里插入图片描述
  • http协议默认是无状态协议
  • http-request中请求行的请求方法最常用的是GETPOST
    • GETPOST方法都支持用户进行参数提交,GET方法提交参数通过URL字段进行提交,POST方法提交参数通过Cotent正文进行提交
  • http报文解析和封装的实验代码:
#pragma once
#include "log.hpp"
#include "Socket.cpp"
#include <pthread.h>
#include <fstream>
#include <unordered_map>
#include <vector>
#include <iostream>
#include <sstream>
//协议请求处理类-->request反序列化处理类
class HttpRequest{const std::string Webroot_ ="./index"; // web 根目录const std::string sep_ = "\r\n";const std::string homepage_ = "index.html";
public://反序列化接口-->获取请求报头和正文字段-->报头存在vector中,text放在string中void Deserialize(std::string request){int begin = 0;while(true){std::size_t pos = request.find(sep_,begin);if(pos == std::string::npos){break;}std::string temp = request.substr(begin, pos-begin);if(temp.empty()){//截取到空行,报头截取完毕begin = pos + sep_.size();break;}req_header_.push_back(std::move(temp));begin = pos + sep_.size();}//截取正文字段text_ = request.substr(begin,request.size() - begin);}//解析http报头第一行的内容,包括请求方法,请求的资源路径,请求的资源url,http协议版本,请求中的服务器资源路径//获取的url是服务器端口号之后的资源路径信息void Parse(){if(req_header_.size() == 0){lg(Warning,"req_header_ is empty\n");return;}//将协议报头的第一行以空格为分隔符,分别存入三个string中std::stringstream Stream(req_header_[0]);Stream >> method_ >> url_ >> http_version_;//从报头第一行的url字段中提取出资源在服务器上的路径和所请求的资源的文件后缀file_path_ = Webroot_;  //前缀加上服务器根目录if(url_ == "/" || url_ == "/index.html"){//构建Web主页路径file_path_ += "/";file_path_ += homepage_;}else{//构建资源在服务器上的路径file_path_ += url_;}//构建所请求的资源的文件后缀auto pos = file_path_.rfind(".");if(pos == std::string::npos){//默认后缀suffix_ = ".html";}else{suffix_ = file_path_.substr(pos);}}//打印客户端请求内容void DebugPrint(){//打印协议报头for(auto &line : req_header_){std::cout << "--------------------------------" << std::endl;std::cout << line << std::endl;}//打印报头解析和正文std::cout << "method: " << method_ << std::endl;std::cout << "url: " << url_ << std::endl;std::cout << "http_version: " << http_version_ << std::endl;std::cout << "file_path: " << file_path_ << std::endl;std::cout << "--------------------------------" << std::endl;std::cout << text_ << std::endl;}
public:std::vector<std::string> req_header_;   //协议报头std::string text_;                      //协议正文字段//http报头解析结果std::string method_;         //请求中的方法std::string url_;            //请求中的url字段std::string http_version_;   //请求中的http协议版本std::string file_path_;      //请求中的资源路径std::string suffix_;         //请求中的待读取的文件后缀
};
  • 服务端接收客户端报文并构建响应的简单服务器:
class http_server{const int size = 4096;class ThreadData{public:ThreadData(int fd, http_server *s) : sockfd(fd), svr(s){}public:int sockfd;http_server *svr;};const std::string Webroot_ ="./index"; // web 根目录const std::string sep_ = "\r\n";const std::string homepage_ = "index.html";
public:http_server(const std::string& de_ip = "172.19.29.44",uint16_t de_port = 8081): socket_(de_ip,de_port){MAP.insert({".html", "text/html"});MAP.insert({".png", "image/png"});}~http_server(){}public:bool Init(){socket_.BuildSocket();socketfd_ = socket_.Get_Server_fd();if(!socket_.SocketBind()){lg(Fatal,"socket bind error\n");return false;}if(!socket_.Socklisten()){lg(Fatal,"socket listen error\n");return false;}return true;}void Start(){while(true){std::string client_ip;uint16_t client_port;int fd = socket_.SockAccept(client_ip,client_port);if(fd < 0){lg(Warning,"Accept error\n");continue;}lg(Info, "get a new connect, sockfd: %d", fd);ThreadData * td = new ThreadData(fd,this);pthread_t tid;pthread_create(&tid,nullptr,Routine,td);}}
private:static void * Routine(void * args){ThreadData * td = static_cast<ThreadData *>(args);pthread_detach(pthread_self());td->svr->HandlerHttp(td->sockfd);delete td;close(td->sockfd);return nullptr;}//处理http请求并构建http回应void HandlerHttp(int sockfd){char buffer[10240];//读取客户端请求ssize_t n = recv(sockfd, buffer, sizeof(buffer) - 1, 0);if (n > 0){buffer[n] = 0;std::cout << buffer << std::endl;//对客户端请求进行解析HttpRequest req;req.Deserialize(buffer);req.Parse();req.DebugPrint();//构建http响应//读取客户端请求的文件资源,构建http响应正文std::string text;bool isFound = true;text = ReadHtmlContent(req.file_path_);if(text.empty()){//客户端请求的资源不存在isFound = false;std::string err_html = Webroot_;err_html += "/";err_html += "err.html";text = ReadHtmlContent(err_html);//读取404页面返回给客户端}//构建http响应报头第一行std::string response_line;if(isFound)response_line = "HTTP/1.0 200 OK\r\n";elseresponse_line = "HTTP/1.0 404 Not Found\r\n";//构建http响应报头中的各个属性字段//正文长度std::string response_header = "Content-Length: ";response_header += std::to_string(text.size());response_header += "\r\n";//正文文件的类型(后缀)response_header += "Content-Type: ";response_header += SuffixToDesc(req.suffix_);response_header += "\r\n";//设置浏览器缓存-->浏览器的下一次请求中url会加上该字段response_header += "Set-Cookie: name=zhounaiqing&&passwd=12345678";response_header += "\r\n";//页面自动跳转定位-->浏览器读到会自动进行页面跳转response_header += "Location: https://www.qq.com\r\n";//构建空行std::string blank_line = "\r\n";//构建完整http回应字段std::string response = std::move(response_line);response += std::move(response_header);response += std::move(blank_line);response += std::move(text);//向客户端发送http回应send(sockfd, response.c_str(), response.size(), 0);}}std::string SuffixToDesc(const std::string &suffix){auto iter = MAP.find(suffix);if(iter == MAP.end()) return MAP[".html"];else return MAP[suffix];}//以二进制的方式读取文件static std::string ReadHtmlContent(const std::string &htmlpath){std::ifstream in(htmlpath, std::ios::binary);if(!in.is_open()){lg(Warning,"Html_File open error\n");return "";} //文件指针定位到文件末尾in.seekg(0, std::ios_base::end);auto len = in.tellg();//文件指针定位到文件开头in.seekg(0, std::ios_base::beg);std::string content;content.resize(len);in.read((char*)content.c_str(), content.size());in.close();return content;}
private:MySocket::Socket socket_;int socketfd_;std::string server_ip_;uint16_t server_port_;std::unordered_map<string,string>MAP;
};

二.https协议加密策略解析

  • https协议是基于http协议的加密通信协议,其很大程度上保证CS两端的数据安全
  • 对称加密:同一个密钥可以进行报文的加密和解密操作
  • 非对称加密:存在公钥私钥,私钥加密的报文由公钥进行解密,公钥加密的报文由私钥进行解密,使用上公钥可以对外公开,私钥保密

加密策略1–通信双方只使用对称加密

在这里插入图片描述

  • 这种加密策略需要双方通信前约定密钥的选择,因此密钥可能外泄,显然是不安全的

加密策略2–通信双方使用单方非对称加密

  • 服务器持有公钥和私钥,通信前,服务器将公钥发给客户端完成加密握手协商,后续客户端的请求报文就通过公钥加密发送给服务器
    在这里插入图片描述
  • 该加密策略显然无法保证服务端的报文安全

加密策略3–通信双方都使用非对称加密

  • 服务器和客户端都各自持有私钥,通信之前双方先交换公钥完成加密握手协商,后续通过公钥加密报文进行通信,这种通信策略的效率较为低下(非对称加密算法复杂度高)
    在这里插入图片描述

加密策略4–非对称加密与对称加密配合使用

  • 服务端持有私钥S,并将公钥S'发送给客户端,客户端利用公钥S',加密自己的对称密钥K并发送给服务端(保证了密钥K不外泄)完成加密握手协商,双方后续使用对称密钥K进行双向通信,这种通信策略的效率较高
    在这里插入图片描述
  • 策略4在四个策略中最优,但是策略2,策略3,策略4在通信前都存在一个加密握手协商的过程,在这个过程中如果存在中间人攻击,进行了密钥置换,就会导致泄密

中间人攻击

  • 以策略4为例:
    在这里插入图片描述
  • 上述密钥置换风险的本质是客户端(或服务端)无法识别公钥本身的真正来源,因此必须引入证书补全这个安全漏洞

数据签名与CA证书

在这里插入图片描述

  • CA证书是由权威机构服务端机构颁发的公钥身份证,用于确保客户端能够识别出公钥来源的合法性,其识别原理的核心在于证书上的数据签名.
  • CA证书上的数据签名是一段由CA机构私钥加密的密文,密文中被加密的内容是证书上数据的哈希映射值(并且是不可逆映射),所有的操作系统在出厂前内置了CA机构公开的公钥,因此客户端可以对CA证书上的数据签名进行解密得到一个原证书数据的哈希散列值Hash1,此时客户端再将证书上的实时数据进行哈希映射得到哈希散列值Hash2,若Hash1Hash2不相同,则说明证书被中间人篡改过,此时客户端可以向用户发出安全性警告.
  • 需要注意的是,数据签名是由CA机构用私钥进行加密的,由于CA机构的私钥是绝对保密的,因此中间人没有办法重新生成新的数据签名,所以数据签名是绝对权威性的
  • CA证书认证过程图解:
    在这里插入图片描述

HTTPS数据安全认证的本质:非对称加密+对称加密+证书认证

  • HTTPS协议工作流程:
    在这里插入图片描述
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/505433.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Spring Boot 源码学习】BootstrapRegistry 初始化器实现

《Spring Boot 源码学习系列》 BootstrapRegistry 初始化器实现 一、引言二、往期内容三、主要内容3.1 BootstrapRegistry3.2 BootstrapRegistryInitializer3.3 BootstrapRegistry 初始化器实现3.3.1 定义 DemoBootstrapper3.3.2 添加 DemoBootstrapper 四、总结 一、引言 前面…

代码随想录算法训练营第46天| 139.单词拆分、背包问题总结

139.单词拆分 完成 思路&#xff1a; 本题可以用背包问题的思路解决&#xff0c;单词是物品&#xff0c;字符串是背包&#xff0c;要求物品能否把背包装满。 dp[j] 字符串长度为j时&#xff0c;能否拆分为一个或多个在字典中出现的单词。 递推公式为&#xff1a;if([i, j] 这个…

【Java文件报错】Cannot resolve symbol ‘println‘ 【及解决】

一、问题描述 在Java源代码文件中&#xff0c;使用 System.out.println() 语句进行输出&#xff0c;编译器提示“Cannot resolve symbol ‘println’&#xff08;无法解释关键字&#xff09;”, println飘红。报错代码及报错截图如下所示。 import java.io.*;public class St…

Leetcode560. 和为 K 的子数组 -hot100

题目&#xff1a; 代码(首刷看解析 2024年3月2日&#xff09;&#xff1a; class Solution { public:int subarraySum(vector<int>& nums, int k) {// 前缀和 遍历int res 0;unordered_map<int, int> sumPre;int sum 0;// 关键&#xff1a;初始化sumPre[0]…

特征融合篇 | YOLOv8 引入通用高效层聚合网络 GELAN | YOLOv9 新模块

今天的深度学习方法专注于如何设计最合适的目标函数,以使模型的预测结果最接近真实情况。同时,必须设计一个合适的架构,以便为预测提供足够的信息。现有方法忽视了一个事实,即当输入数据经过逐层特征提取和空间转换时,会丢失大量信息。本文将深入探讨数据通过深度网络传输…

nn.Linear() 使用提醒

原本以为它是和nn.Conv2d()一样&#xff0c;就看第二个维度的数值&#xff0c;今天才知道&#xff0c;它是只看最后一个维度的数值&#xff01;&#xff01;&#xff01; 例子1 Descripttion: Result: Author: Philo Date: 2024-02-27 14:33:50 LastEditors: Philo LastEditT…

Windows命令行工具和PowerShell介绍

Windows命令行工具和PowerShell是两种不同的文本界面命令解释器&#xff0c;它们在Windows操作系统中用于执行各种操作和管理任务。虽然它们都可以用于执行命令和脚本&#xff0c;但它们之间存在着一些区别和特点。 1. Windows命令行工具&#xff08;Cmd.exe&#xff09; …

xxl-job--01--简介

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1.xxl-job1. 1 发展历史1.2 XXL-JOB的系统架构1.3 xxl-job与其他框架对比 2. XXL-JOB的使用2.1 准备工作- 配置调度中心XXL-JOB的数据表 2.2 配置执行器1 引入依赖包…

2023,九章云极DataCanvas的澎湃时刻

大模型和AIGC成就了2023。九章云极DataCanvas公司的2023充满生命力&#xff0c;是人工智能基础软件创新浓度最高的一年&#xff0c;也是价值释放最具想象力的一年。 人工智能新时代的热潮席卷而来&#xff0c;九章云极DataCanvas公司以过硬的AI技术响应时代&#xff0c;冲锋智…

Datawhale【Sora原理与技术实战】| 学习笔记

目录 一. Sora能力二. Sora训练流程1. Visusal encoder2. Diffusion Transformer3. Transformer Decoder 一. Sora能力 长视频&#xff1a;最大可支持60s高清视频生成保持人物与场景高度统一视频融合能力强同一场景多角度/多镜头涌现&#xff1a;随着运动镜头的变化&#xff0…

中央处理器CPU中的技术

一、 知识加油站 1. cpu 指令的执行过程 取指&#xff1a;cpu 获取 程序计数器 中存放的指令地址。读取内存中此地址对应指令并存入指令寄存器译码&#xff1a;指令译码器&#xff0c;解析指令运行&#xff1a;算数逻辑单元计算回写&#xff1a;将执行结果写入对应位置 二. …

Julia语言中的位运算符、赋值运算符、算术运算符

算术运算符 # 使用基本的赋值运算符 a 10 println("a 的初始值是: $a") # 使用加法赋值运算符 a 5 println("a 加上 5 后的值是: $a") # 使用减法赋值运算符 - a - 3 println("a 减去 3 后的值是: $a") # 使用乘法赋值运算符…