应用层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.mzph.cn/news/715350.shtml

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

相关文章

二维码门楼牌管理系统技术服务的分类与应用

文章目录 前言一、二维码门楼牌管理系统的分类二、二维码门楼牌管理系统的应用优势三、结论 前言 随着城市管理的精细化和智能化&#xff0c;二维码门楼牌管理系统成为了现代城市管理的重要工具。该系统将传统的门牌、楼牌、户牌与二维码技术相结合&#xff0c;实现了信息的快…

MySQL:常用的SQL语句

提醒&#xff1a;设定下面的语句是在数据库名为 db_book执行的。 一、创建表 1. 创建t_booktype表 USE db_book; CREATE TABLE t_booktype(id INT AUTO_INCREMENT, bookTypeName VARCHAR(20),bookTypeDesc varchar(200),PRIMARY KEY (id) );2. 创建t_book表 USE db_book; C…

C语言-----动态内存管理(1)

1.引入 我们之前已经学习了几种开辟内存空间的方式&#xff1a; &#xff08;1&#xff09;int a10;开辟4个字节大小的空间 &#xff08;2&#xff09;int arr[10]{0}定义数组开辟了一串连续的空间 2.malloc和free (1)malloc开辟内存空间可能会失败&#xff0c;因此需要检查…

HTML5+CSS3+JS小实例:文字阴影还能这么玩

实例:文字阴影还能这么玩 技术栈:HTML+CSS+JS 效果: 源码: 【HTML】 <!DOCTYPE html> <html lang="zh-CN"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge"…

鸿蒙Harmony应用开发—ArkTS声明式开发(通用属性:形状裁剪)

用于对组件进行裁剪、遮罩处理。 说明&#xff1a; 从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 clip clip(value: boolean | CircleAttribute | EllipseAttribute | PathAttribute | RectAttribute) 按指定的形状对当…

中美加密监管突传“巨响”!比特币突破7万信号出现!马斯克一句话掀起大行情!

比特币本周触及64000美元高价&#xff0c;2月交易所储备减少近45000多枚比特币&#xff0c;市场将其解读为看涨70000美元的关键信号。中美加密监管传利好&#xff0c;香港加密牌照申请期限结束&#xff0c;已有24家机构入列待批&#xff0c;美国考虑允许比特币ETF及相关信托期权…

uview2中上传文件和若依前后端分离配合的代码

uview2中的上传文件需要配合着自己后端的上传的代码 uview2 代码&#xff1a; uploadFilePromise(url) {return new Promise((resolve, reject) > {// 后续自己封装let a uni.uploadFile({//自己的请求路径url: that.$baseURL /uploadAvater, //上传的文件filePath: tha…

Java | vscode如何使用命令行运行Java程序

1.在vscode中新建一个终端 2.在终端中输入命令 javac <源文件>此命令执行后&#xff0c;在文件夹中会生成一个与原java程序同名的.class文件。然后输入如下命令&#xff1a; java <源文件名称>这样java程序就运行成功了。&#x1f607;

LeetCode:2368. 受限条件下可到达节点的数目(dfs Java)

目录 2368. 受限条件下可到达节点的数目 题目描述&#xff1a; 实现代码与解析&#xff1a; DFS 原理思路&#xff1a; 2368. 受限条件下可到达节点的数目 题目描述&#xff1a; 现有一棵由 n 个节点组成的无向树&#xff0c;节点编号从 0 到 n - 1 &#xff0c;共有 n - …

02-Vue 计算属性与监听器与VUE-cli使用

1.计算属性 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width,…

单源最短路的建图方式

1129. 热浪 - AcWing题库 这道题可以有三种方法来做&#xff0c;朴素版的dijkstra、堆优化版的dijkstra和spfa算法 &#xff08;1&#xff09;spfa算法 这里的队列用循环队列&#xff0c;而不是像模板那样用普通队列是因为它的队列长度不确定 import java.util.*;public class…

贝叶斯优化CNN分类(matlab代码)

贝叶斯优化CNN分类matlab代码 数据为Excel分类数据集数据。 数据集划分为训练集、验证集、测试集&#xff0c;比例为8:1:1 数据处理: 在数据加载后&#xff0c;对数据进行了划分&#xff0c;包括训练集、验证集和测试集&#xff0c;这有助于评估模型的泛化能力。 数据标准化…

动态规划(算法竞赛、蓝桥杯)--树形DP没有上司的舞会

1、B站视频链接&#xff1a;E17 树形DP Luogu P1352 没有上司的舞会_哔哩哔哩_bilibili 题目链接&#xff1a;没有上司的舞会 - 洛谷 #include <bits/stdc.h> using namespace std; const int N6010; int n; int w[N]; vector<int>a[N];//邻接表 bool fa[N]; int…

011 Linux_线程概念与创建

前言 本文将会向你介绍线程的概念&#xff0c;以及线程是怎么被创建的 线程概念 一、进程是承担系统资源的基本实体&#xff0c;线程是cpu调度的基本单位 首先&#xff0c;地址空间在逻辑上相当于进程的资源窗口&#xff0c; 每个进程都有这样一个资源窗口。通过地址空间页…

前端面试知识点合集

原型和原型链 任何函数都可以作为构造函数。当该函数通过 new 关键字调用的时候&#xff0c;就称之为构造函数。 var Parent function(){}//定义一个函数&#xff0c;那它只是一个普通的函数&#xff0c;不能称它为构造函数var instance new Parent(); //这时这个Parent就不…

C#理论 —— WPF 应用程序Console 控制台应用

文章目录 1. WPF 应用程序1.1 工程创建1.2 控件1.2.1 控件的公共属性1.2.1 TextBox 文本框1.2.1 Button 按钮 *. Console 控制台应用1.1 工程创建 1. WPF 应用程序 1.1 工程创建 Visual Studio 中新建项目 - 选择WPF 应用程序&#xff1b; 1.2 控件 1.2.1 控件的公共属性 …

Linux网络编程——网络基础

Linux网络编程——网络基础 1. 网络结构模式1.1 C/S 结构1.2 B/S 结构 2. MAC 地址3. IP地址3.1 简介3.2 IP 地址编址方式 4. 端口4.1 简介4.2 端口类型 5. 网络模型5.1 OSI 七层参考模型5.2 TCP/IP 四层模型 6. 协议6.1 简介6.2 常见协议6.3 UDP 协议6.4 TCP 协议6.5 IP 协议6…

【兔子机器人】根据自身机器人参数修改simulink模型

关节电机 机体初始高度 &#xff01;&#xff01;&#xff01;接下来尝试修改各腿的坐标朝向

LeetCode54题:螺旋矩阵(python3)

路径的长度即为矩阵中的元素数量&#xff0c;当路径的长度达到矩阵中的元素数量时即为完整路径&#xff0c;将该路径返回。 循环打印&#xff1a; “从左向右、从上向下、从右向左、从下向上” 四个方向循环打印。 class Solution:def spiralOrder(self, matrix: List[List[i…

怎么对App进行功能测试

测试人员常被看作是bug的寻找者&#xff0c;但你曾想过他们实际是如何开展测试的吗&#xff1f;你是否好奇他们究竟都做些什么&#xff0c;以及他们如何在一个典型的技术项目中体现价值&#xff1f;本文将带你经历测试人员的思维过程&#xff0c;探讨他们测试app时的各种考虑. …