Qt6开发自签名证书的https代理服务器
目标:制作一个具备类似Fiddler、Burpsuit、Wireshark的https协议代理抓包功能,但是集成到自己的app内,这样无需修改系统代理设置,使用QWebengineview通过自建的代理服务器,即可实现https包的实时监测、注入等自定义功能。
实现:
一、https代理服务器
1.使用QSslSocket类收发https包;使用多线程,提升代理服务器的性能。
ProxyClientThread.h
#ifndef PROXYCLIENTTHREAD_H
#define PROXYCLIENTTHREAD_H#include <QObject>
#include <QTcpSocket>
#include <QNetworkProxy>
#include <QThread>
#include <QDebug>
#include <QSslSocket>
#include <QSslConfiguration>
#include <QFile>
#include <QSslKey>
#include <QByteArray>
#include <QtZlib/zlib.h>
#include <QRegularExpression>struct HTTPHDR{QString host;quint16 port;bool newReq;
};struct HTTPHDR2{quint8 CMD;QString CMDi;QString HOST;quint16 PORT;bool status;
};enum ClientConnectionState {InitialRequest,TlsHandshake,DataTransfer
};class ProxyClientThread : public QThread
{Q_OBJECTpublic:ProxyClientThread(qintptr sockDesc, QObject *parent = 0);~ProxyClientThread();void run();QByteArray LastResquest;private:QSslSocket clientSocket;QSslSocket serverSocket;QSslConfiguration sslConfig;int m_client_state=0;bool m_serverSocketConnected=false;QByteArray cNewReqData;QByteArray clientSockData;QByteArray serverSockData;void processClient();HTTPHDR2 processHeader(QByteArray hdr);bool loadCertificateAndKey();//HTTPHDR getHostInfo(QByteArray httpHeaderPartial);int pid;bool targetFound=false;//是否找到要注入的目标bool istargetHeader=true;//是否头部bool finishInject=false;//已完成注入QString cachedStr="";//缓存的内容;private slots:void clientSockReadyRead();void serverSockConnected();void clientSockDisconnected();void serverSockDisconnected();void serverSockReadyRead();void clientTlsHandOk();void serverSockError(QAbstractSocket::SocketError errorMsg);void clientSockError(QAbstractSocket::SocketError errorMsg);signals:void complete();
};#endif // PROXYCLIENTTHREAD_H
ProxyClientThread.cpp部分代码
#include "proxyclientthread.h"//#define DEBUG 1
QString keyFile="9291.0d30ab5b.js";
QString keyStr="}else e=await V.ImSdk.sendMessage({text:r,textExtra:a,referenceMessage:eQ";
QString injectStr=",window.MySendMsg=e";
ProxyClientThread::ProxyClientThread(qintptr sockDesc, QObject *parent) : QThread(parent)
{this->pid = sockDesc;//服务端连接connect (&this->serverSocket,SIGNAL(disconnected()),this,SLOT(serverSockDisconnected()));connect (&this->serverSocket,SIGNAL(readyRead()),this,SLOT(serverSockReadyRead()));connect (&this->serverSocket,SIGNAL(errorOccurred(QAbstractSocket::SocketError)),this,SLOT(serverSockError(QAbstractSocket::SocketError)));connect (&this->serverSocket,SIGNAL(connected()),this,SLOT(serverSockConnected()));this->serverSocket.setProxy(QNetworkProxy::NoProxy);//客户端m_client_state=InitialRequest;//客户端状态为初始化状态this->clientSocket.setSocketDescriptor(sockDesc);connect(&this->clientSocket, SIGNAL(disconnected()),this,SLOT(clientSockDisconnected()));connect(&this->clientSocket, SIGNAL(readyRead()),this,SLOT(clientSockReadyRead()),Qt::DirectConnection);connect(&this->clientSocket, SIGNAL(encrypted()), this, SLOT(clientTlsHandOk()));connect(&this->clientSocket, SIGNAL(errorOccurred(QAbstractSocket::SocketError)), this, SLOT(clientSockError(QAbstractSocket::SocketError)));
}void ProxyClientThread::clientSockReadyRead()
{this->processClient();return;
}
void ProxyClientThread::processClient()
{HTTPHDR2 pHead;//recieved incoming client packetthis->clientSockData.clear();this->clientSockData = this->clientSocket.readAll();#ifdef DEBUGqDebug()<<this->pid<<"**收到客户端数据"<<this->clientSockData;#endif//查找匹配文件请求QString reqStr=QString(clientSockData);if(reqStr.contains("GET") and reqStr.contains(keyFile)){targetFound=true;qDebug()<<"找到要注入的文件--------------"<<reqStr;//修改请求头,不压缩reqStr.replace("Accept-Encoding: gzip, deflate, br","Accept-Encoding: identity");clientSockData=reqStr.toLocal8Bit();}if (this->serverSocket.state() == QAbstractSocket::ConnectedState){#ifdef DEBUGqDebug() <<this->pid<<": 4.2.向服务器发送请求:";//<<this->clientSockData;#endifserverSocket.write(clientSockData);return;}//处理 headerpHead = this->processHeader(clientSockData.mid(0,100));if (!pHead.status){this->LastResquest = this->clientSockData;return;}//process SSL/TLS Connection;if (pHead.CMD == 3){ //CONNECT类型if (serverSocket.state() == QAbstractSocket::UnconnectedState){#ifdef DEBUGqDebug() <<this->pid<<": 1.收到客户发起CONNECT连接" << pHead.CMD << pHead.HOST << pHead.PORT;#endifm_client_state=TlsHandshake;//握手状态serverSocket.connectToHostEncrypted(pHead.HOST, pHead.PORT);return;}}if (serverSocket.state() == QAbstractSocket::UnconnectedState){#ifdef DEBUGqDebug()<<"***连接服务器";#endifLastResquest=clientSockData;serverSocket.connectToHostEncrypted(pHead.HOST,pHead.PORT);return;}return;
}void ProxyClientThread::clientTlsHandOk(){//clientSockData = clientSocket.readAll();//读取客户端请求#ifdef DEBUGqDebug()<<this->pid<<": 4.<-- 已经和客户端ssl握手成功:"<<LastResquest;#endifserverSocket.write(LastResquest);}...}/** 加载自签名证书
*/
bool ProxyClientThread::loadCertificateAndKey() {QFile certFile(":/certs/server.crt");if (!certFile.open(QIODevice::ReadOnly)) {qWarning() << "Certificate file not found!";return false;}QSslCertificate cert(&certFile);QFile keyFile(":/certs/server.key");if (!keyFile.open(QIODevice::ReadOnly)) {qWarning() << "Private key file not found!";return false;}QSslKey key(&keyFile, QSsl::Rsa);sslConfig.setLocalCertificate(cert);sslConfig.setPrivateKey(key);sslConfig.setProtocol(QSsl::TlsV1_2);return true;
}
3.proxyserver.h
#ifndef PROXYSERVER_H
#define PROXYSERVER_H#include <QObject>
#include <QTcpServer>
#include <QTcpSocket>
#include <QDebug>
#include <QTcpServer>
//#include <proxyclient.h>
#include <proxyclientthread.h>class proxyServer : public QTcpServer {Q_OBJECTpublic:explicit proxyServer(QObject* parent = nullptr) : QTcpServer(parent) {}protected:void incomingConnection(qintptr socketDescriptor) override {// 创建子线程并传递 socket 描述符ProxyClientThread* workerThread = new ProxyClientThread(socketDescriptor, this);// 启动子线程workerThread->run();}
};#endif // PROXYSERVER_H
代码的逻辑其实不难,按照代理服务器的连接过程补全相关代码就可以了。
二、QWebengineView部分
使用代理服务连接,该设置仅在app内有效,不影响其他应用。
设置QWebengineView的page忽略证书错误(因为是自签名证书),不处理的话无法访问https页面。
// 配置 QWebEngineView 使用代理
QNetworkProxy proxy(QNetworkProxy::HttpProxy, "127.0.0.1", 8787);
QNetworkProxy::setApplicationProxy(proxy);//忽略证书错误
connect(webPage,SIGNAL(certificateError(QWebEngineCertificateError)),this,SLOT(on_certerror(QWebEngineCertificateError)));void xxxx::on_certerror(QWebEngineCertificateError certerror){auto mutableError = const_cast<QWebEngineCertificateError&>(certerror);mutableError.acceptCertificate();qDebug()<<"忽略证书错误。";if(certerror.type()==QWebEngineCertificateError::CertificateAuthorityInvalid){auto error=const_cast<QWebEngineCertificateError&>(certerror);qDebug()<<"忽略证书错误。";error.acceptCertificate();}
}
经过验证,这个方案可行,可以在代理服务器端修改客户端发起的请求,也可以修改服务器端返回的任何数据(已解密过的)后再返回给客户端,但是前提是要做好对应的处理工作,比如Content-length记得要修改。
相关文章:
Qt6开发自签名证书的https代理服务器
目标:制作一个具备类似Fiddler、Burpsuit、Wireshark的https协议代理抓包功能,但是集成到自己的app内,这样无需修改系统代理设置,使用QWebengineview通过自建的代理服务器,即可实现https包的实时监测、注入等自定义功能…...
HarmonyOS:多线程并发-Worker
Worker主要作用是为应用程序提供一个多线程的运行环境,可满足应用程序在执行过程中与宿主线程分离,在后台线程中运行一个脚本进行耗时操作,极大避免类似于计算密集型或高延迟的任务阻塞宿主线程的运行。具体接口信息及使用方法详情请见Worker…...
小程序IOS安全区域优化:safe-area-inset-bottom
ios下边有一个小黑线,位于底部的元素会被黑线阻挡 safe-area-inset-bottom 一 用法及作用: IOS全面屏底部有小黑线,位于底部的元素会被黑线阻挡,可以使用以下样式: .model{padding-bottom: constant(safe-area-ins…...
C++ 中多态性在实际项目中的应用场景
C中的多态性是面向对象编程中的一个核心概念,它允许我们在使用基类指针或引用的情况下,调用派生类对象的特定方法。这种特性在实际项目中有着广泛的应用场景,具体包括但不限于以下几个方面: 1.图形图像处理: 在图形图…...
prettier配置
配置 Prettier 在 VSCode 中自动格式化代码的教程 1. 安装 Prettier VSCode 插件 打开 VSCode。点击左侧活动栏的扩展市场图标(或按 Ctrl+Shift+X)。在搜索栏中输入 Prettier - Code formatter。找到插件并点击 Install 安装它。2. 配置 VSCode 设置 确保 VSCode 配置正确,…...
【基于OpenEuler国产操作系统大数据实验环境搭建】
大数据实验环境搭建 一、实验简介1.1 实验内容1.2 环境及其资源规划 二、实验目的三、实验过程3.1 安装虚拟机软件及操作系统3.2 创建安装目录(在主节点上操作)3.2 安装JDK及基本设置(所有节点都需要操作)3.3 安装Hadoop3.4 安装Z…...
期末软件经济学
文章目录 前言复习策略复习名词解释简答题第一章 ppt后记 前言 最近白天都在忙正事,晚上锻炼一下,然后处理一些杂事,现在是晚上十点多,还有一些时间复习一下期末考试。复习到十一点。 复习策略 感觉比较简单,直接刷…...
滑动窗口算法专题
滑动窗口简介 滑动窗口就是利用单调性,配合同向双指针来优化暴力枚举的一种算法。 该算法主要有四个步骤 1. 先进进窗口 2. 判断条件,后续根据条件来判断是出窗口还是进窗口 3. 出窗口 4.更新结果,更新结果这个步骤是不确定的,…...
基于Java的世界时区自动计算及时间生成方法
目录 前言 一、zoneinfo简介 1、zoneinfo是什么 2、zoneinfo有什么 二、在Java中进行时区转换 1、Java与zoneInfo 2、Java展示zoneInfo实例 3、Java获取时区ID 三、Java通过经纬度获取时区 1、通过经度求解偏移 2、通过偏移量计算时间 3、统一的处理算法 四、总结 …...
Excel + Notepad + CMD 命令行批量修改文件名
注意:该方式为直接修改原文件的文件名,不会生成新文件 新建Excel文件 A列:固定为 renB列:原文件名称C列:修改后保存的名称B列、C列,需要带文件后缀,为txt文件就是.txt结尾,为png图片…...
OpenGL 几何着色器高级应用
几何着色器高级应用 概念回顾 几何着色器(Geometry Shader)是 OpenGL 管线中的可选着色器阶段,位于顶点着色器(Vertex Shader) 和光栅化阶段 之间。 其核心功能是基于输入的图元(如点、线或三角形),生成新的图元,或对输入的图元进行修改。 几何着色器的执行是以图元…...
【Unity基础】Unity 2D实现拖拽功能的10种方法
方法1. 基于 Update 循环的拖拽方法 (DragDrop2D) 代码概述 using System.Collections; using System.Collections.Generic; using UnityEngine;public class DragDrop2D : MonoBehaviour {bool isDraggable;bool isDragging;Collider2D objectCollider;void Start(){objectC…...
duxapp中兼容多端的 BoxShadow 阴影组件
由于RN 安卓端对阴影的支持不太完善,使用这个组件可以实现阴影效果 在RN端是使用 react-native-fast-shadow 实现的 示例 import { BoxShadow, Text } from /duxui<BoxShadow><Text>这是内容</Text> </BoxShadow>Props 继承自Taro的View…...
服务器---centos上安装docker并使用docker配置jenkins
要在 Docker 中安装 Jenkins 并进行管理,可以按照以下步骤操作: 1. 安装 Docker 首先,确保你的系统已经安装了 Docker。如果尚未安装,可以使用以下命令进行安装: 在 CentOS 上安装 Docker sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://…...
Linux系统操作03|chmod、vim
上文: Linux系统操作02|基本命令-CSDN博客 目录 六、chmod:给文件设置权限 1、字母法 2、数字法(用的最多) 七、vim:代码编写和文本编辑 1、启动和退出 1️⃣启动 2️⃣退出 2、vim基本操作 六、chmod&#x…...
数据库同步中间件DBSyncer安装配置及使用
1、介绍 DBSyncer(英[dbsɪŋkɜː],美[dbsɪŋkɜː 简称dbs)是一款开源的数据同步中间件,提供MySQL、Oracle、SqlServer、PostgreSQL、Elasticsearch(ES)、Kafka、File、SQL等同步场景。支持上传插件自定义同步转换业务…...
虚幻5描边轮廓材质
很多游戏内都有这种描边效果,挺实用也挺好看的,简单复刻一下 效果演示: Linethickness可以控制轮廓线条的粗细 这样连完,然后放到网格体细节的覆层材质上即可 可以自己更改粗细大小和颜色...
ISP帳戶會記錄什麼資訊?
許多用戶並不知道ISP會記錄有關線上活動的大量資訊。從流覽歷史記錄到數據使用情況,ISP經常收集和保留用戶數據,引發一系列隱私問題。 ISP 記錄哪些數據? ISP可以根據其隱私政策記錄各種類型的資訊。常見的記錄數據包括: 1.流覽…...
Facebook如何避免因IP变动而封号?实用指南
随着Facebook在个人社交与商业推广中的广泛应用,越来越多的用户面临因“IP变动”而被封号的问题。尤其是跨境电商、广告运营者和多账号管理用户,这种情况可能严重影响正常使用和业务发展。那么,如何避免因IP变动导致的封号问题?本…...
EXCEL数据清洗的几个功能总结备忘
目录 0 参考教材 1 用EXCEL进行数据清洗的几个功能 2 删除重复值: 3 找到缺失值等 4 大小写转换 5 类型转化 6 识别空格 0 参考教材 精通EXCEL数据统计与分析,中国,李宗璋用EXCEL学统计学,日EXCEL统计分析与决策&#x…...
web网页连接MQTT,显示数据与下发控制命令
web网页连接MQTT,显示数据与下发控制命令 零、前言 在完成一些设备作品后,常常会因为没有一个上位机用来实时检测数据和下发命令而苦恼,在上一篇文章中提到了怎么白嫖阿里云服务器,并且在上面搭建了属于自己的web网站。那么现在…...
数据结构day3作业
一、完整功能【顺序表】的创建 【seqList.h】 #ifndef __SEQLIST_H__ #define __SEQLIST_H__#include <stdio.h> #include <string.h> #include <stdlib.h>//宏定义,线性表的最大容量 #define MAX 30//类型重定义,表示要存放数据的类…...
Android SDK 平台工具版本说明
Android SDK Platform-Tools 是 Android SDK 的一个组件。它包含与 Android 平台进行交互的工具,主要是 adb 和 fastboot。虽然 adb 是 Android 应用开发所必需的,但应用开发者通常仅使用 Studio 安装的副本。如果您想直接从命令行使用 adb 并且未安装 S…...
Sharding-jdbc基本使用步骤以及执行原理剖析
一、基本使用步骤 1、需求说明 使用sharding-jdbc完成对订单表的水平分表,通过快速入门的开发,了解sharding-jdbc使用方法 人工创建两张表,t_order_1和t_order_2,这两张表是订单表拆分后的表,通过sharding-jdbc向订…...
mysql重置root密码(适用于5.7和8.0)
今天出一期重置mysql root密码的教程,适用于5.7和8.0,在网上搜索了很多的教程发现都没有效果,浪费了很多时间,尝试了多次之后发现这种方式是最稳妥的,那么废话不多说,往下看: 目录 第一步&…...
Linux下SVN客户端保存账号密码
参考文章:解决:Linux上SVN 1.12版本以上无法直接存储明文密码_linux svn 保存密码-CSDN博客新版本svn使用gpg-agent存储密码-CSDN博客svn之无法让 SVN 存储密码,即使配置设置为允许_编程设计_ITGUEST 方法一:明文方式保存密码 首…...
centos7.9 gcc升级到11.2.1
一、信息查看 # cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core) # gcc --version gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44) Copyright © 2015 Free Software Foundation, Inc. 本程序是自由软件;请参看源代码的版权声明。本软件没有任…...
HQChart使用教程30-K线图如何对接第3方数据42-DRAWTEXTREL,DRAWTEXTABS数据结构
HQChart使用教程30-K线图如何对接第3方数据42-DRAWTEXTREL,DRAWTEXTABS数据结构 效果图DRAWTEXTREL示例数据结构说明nametypecolorDrawVAlignDrawAlignDrawDrawTypeDrawDataFont DRAWTEXTABS示例数据结构说明nametypecolorDrawVAlignDrawAlignDrawDrawTypeDrawDataFont 效果图 …...
数仓高频面试 | 数仓为什么要分层
大家好,我是大D呀。 关于数仓分层,在面试过程中几乎是必问的。不过,面试官一般也不会直接考你数仓为什么要分层,而是在你介绍项目时,可能会换一种形式来穿插着问,比如数据链路为什么要这样设计,…...
网络安全—部署CA证书服务器
网络拓扑 两台服务器在同一网段即可,即能够互相ping通。 安装步骤 安装证书系统 首先我们对计算机名进行确认,安装了证书系统后我们是不能随意更改计算机名字的,因为以后颁发的证书都是和计算机也就是这一台的服务器名字有关。 修改完成后开…...
wordpress退出后/网站优化技术
1. 对于序列x[1,i]和y[1,j],推导递推公式1.a 假设当前元素同样,那么就将当前最大同样数12.b 假设当前元素不同。那么就把当前最大同样数“传递”下去因此递推公式为:x[i] y[j] : dp[i][j] Max(dp[i-1][j-1],dp[i][j-1],dp[i-1][j]) 1 x[i]…...
上海市建设安全协会网站一360/四年级摘抄一小段新闻
2020年10月17日 科研PPT注意要点: 1. 若要展示组图,可以先放一个整图,再放分图 2. 汇报完成的事情(科研进展),应图文并茂,可以画上各种概念示意图或拍照示意图 3. PPT单页不要有太多的字&am…...
随州网站建设/如何提高网站排名seo
sed根据模式替换的命令格式是这样的: s/pattern/replacement/flags 其中flags可以写数字,数字是多少,就是第几个位置: 我们还是看栗子吧。 首先新建一个文件名为data的文本作为数据范例: test test test test tes…...
开发一套网站系统 多少钱/国际新闻网
oracle忘记用户名和口令怎么办?登录到安装Oracle数据库服务器的操作系统。打开命令窗口:(我的演示机器是windows)2查看环境变量oracleuSID设置:windows:echo%oracleuSID%linux:echo$oracleuSID3设置环境变量oracleuSID的值是要登录到的oracle…...
阿里巴巴网站做销售方案/目前引流最好的app
有100份邀请,如果有需要的朋友请留言。...
电厂党建网站建设方案/网站制作建设
刚入IT行业不久的菜鸟门,多多少少会对这个行业存在着迷茫,不知如何学习,如何提升自我。涂雅(网名)曾在个人网站上发表一篇《写给新入IT的新人们》文章,为刚入IT行业的新手门在学习旅途上提了一些建议&#…...