cpprestsdk https双向认证小测

概述

因项目需要在系统中引入https双向认证,由于程序使用C/C++和cpprestsdk库编写,从网上经过一顿检索折腾,总算测试通过,故而博文记录用以备忘。

系统环境

Ubuntu 22.04.3 LTS
libcpprest-dev(jammy,now 2.10.18-1build2 amd64)

步骤

  1. 参考自签名根证书、中间证书、服务器证书生成流程详解,生成根证书、服务器证书以及客户端证书,然后用根证书对服务器、客户端的证书进行签名
  2. 编写代码,具体代码看后面
  3. 测试
    测试可以使用curl
    curl命令
curl -v -k --cacert root_cert.pem --cert client_cert.pem --key client_key.pem https://ip:port/

注意:
使用自签名证书的时候,服务器端的证书Common Name字段一定要填写对应的IP,不然会出现SSL握手失败的情况。

服务端代码

#include <cpprest/http_listener.h>
#include <cpprest/json.h>
#include <string>using namespace std;
using namespace web;
using namespace web::http;
using namespace web::http::experimental::listener;
namespace net = boost::asio;
namespace ssl = net::ssl;bool verify_callback(bool preverified, boost::asio::ssl::verify_context& ctx)
{char subject_name[256];X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256);std::cout << "subject_name:" << subject_name << std::endl;return true;
}int main(int argc, char *argv[]) {string host = "192.168.25.112";int port = 6000;string url = "https://" + host + ":" + to_string(port);http_listener_config conf;string cert = "./certs/server_cert.pem";string privkey = "./certs/server_key.pem";string rootcert = "./certs/root_cert.pem";conf.set_ssl_context_callback([&cert, &privkey, &rootcert](ssl::context &ctx) {try {ctx.set_options(ssl::context::default_workarounds |ssl::context::no_sslv2 | ssl::context::no_tlsv1 |ssl::context::no_tlsv1_1 | ssl::context::single_dh_use);//设置自签名的根证书ctx.load_verify_file(rootcert);//设置根证书签发的服务器证书ctx.use_certificate_chain_file(cert);//设置服务器证书的私钥ctx.use_private_key_file(privkey, ssl::context::pem);//设置验证模式 - 验证对端证书// boost::asio::ssl::verify_fail_if_no_peer_cert 这个必须设置,不然对端不发送证书的时候,服务器是默认通过ctx.set_verify_mode(boost::asio::ssl::verify_peer | boost::asio::ssl::verify_fail_if_no_peer_cert);//设置认证回调,具体作用,没太搞懂ctx.set_verify_callback(verify_callback);//私钥有密码的情况,通过该回调返回密码//ctx.set_password_callback([]() { return "PASSWORD";});} catch (exception const &e) {clog << "ERROR: " << e.what() << endl;}});http_listener listener = http_listener(utility::conversions::to_string_t(url), conf);listener.support(methods::GET, [](web::http::http_request request) {request.reply(status_codes::OK,U("hello world"));});listener.open().wait();while(true) {sleep(100);}cout << "Listening for requests at: " << host << ":" << port << endl;
}

客户端代码

#define _TURN_OFF_PLATFORM_STRING
#include <cpprest/http_client.h>
#include <cpprest/json.h>
#include <string>using namespace std;
using namespace web;
using namespace web::http;
using namespace web::http::client;
namespace net = boost::asio;
namespace ssl = net::ssl;int main(int argc, char *argv[])
{string host = "192.168.25.112";int port = 6000;string url = "https://" + host + ":" + (to_string(port));string rootcert = "./certs/root_cert.pem";string privkey = "./certs/client_key.pem";string cert = "./certs/client_cert.pem";http_client_config conf;try{conf.set_ssl_context_callback([&cert, &privkey, &rootcert](boost::asio::ssl::context &ctx){// 加载根证书ctx.load_verify_file(rootcert);// 加载根证书签发的客户端证书ctx.use_certificate_chain_file(cert);// 加载客户端证书的私钥ctx.use_private_key_file(privkey, ssl::context::pem);// 设置验证模式 - 验证对端ctx.set_verify_mode(boost::asio::ssl::verify_peer);// 私钥有密码的情况,通过该回调返回密码// ctx.set_password_callback([]() { return "PASSWORD";});});http_client client(uri_builder(url).to_uri(), conf);http_response response = client.request(methods::GET, "/").get();// Check the status code.if (response.status_code() != 200){throw std::runtime_error("Returned " + std::to_string(response.status_code()));}// Read the response body as a string.auto response_body = response.extract_string().get();// Output the response body for debugging.std::cout << "Response Body: " << response_body << std::endl;}catch (const std::runtime_error &e){std::cerr << "Exception caught: " << e.what() << __FILE__ << __FUNCTION__ << __LINE__ << std::endl;}catch (std::exception const &e){clog << "ERROR: " << e.what() << endl;}
}

注意:
以上代码只是在自签名证书下验证过,对于正式环境签发的证书,请自行尝试。

Q&A

Q: SSL握手返回,alert number 80
A: 我不知道咋出现的,只有服务器证书的Common Name不一致的情况,该问题会出现


Q: SSL握手返回, Unknown CA
A: 通过ctx.load_verify_file(rootcert);加载根证书即可

参考链接

自签名根证书、中间证书、服务器证书生成流程详解
HTTPS client server in unix
联盟链系列 - Https双向验证
基于boost和QT 实现客户端/服务端TCP双向证书认证与SSL加密
https双向认证

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

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

相关文章

【Text2SQL 论文】DIN-SQL:分解任务 + 自我纠正 + in-context 让 LLM 完成 Text2SQL

论文&#xff1a;DIN-SQL: Decomposed In-Context Learning of Text-to-SQL with Self-Correction ⭐⭐⭐⭐ NeurIPS 2023, arXiv:2304.11015 Code: Few-shot-NL2SQL-with-prompting | GitHub 文章目录 一、论文速读1.1 Schema Linking Module1.2 Classification & Decompo…

【每日刷题】Day52

【每日刷题】Day52 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 2965. 找出缺失和重复的数字 - 力扣&#xff08;LeetCode&#xff09; 2. 350. 两个数组的交集 II …

kaggle竞赛系列基于图像对水稻分类代码案例

目录 依赖环境 代码 导入依赖包 定义数据集路径&#xff1a; 创建训练集、验证集和测试集的文件夹&#xff1a; 代码的作用&#xff1a; 设置新的数据集路径与类别名称 代码的作用&#xff1a; 定义数据预处理和增强变换&#xff1a; 代码的作用&#xff1a; 定义数…

【源码】多语言H5聊天室/thinkphp多国语言即时通讯/H5聊天室源码/在线聊天/全开源

多语言聊天室系统&#xff0c;可当即时通讯用&#xff0c;系统默认无需注册即可进入群聊天&#xff0c;全开源 【海外聊天室】多语言H5聊天室/thinkphp多国语言即时通讯/H5聊天室源码/在线聊天/全开源 - 吾爱资源网

每日5题Day13 - LeetCode 61 - 65

每一步向前都是向自己的梦想更近一步&#xff0c;坚持不懈&#xff0c;勇往直前&#xff01; 第一题&#xff1a;61. 旋转链表 - 力扣&#xff08;LeetCode&#xff09; /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;…

STM32学习和实践笔记(32):电容触摸按键实验

1.电容触摸按键原理介绍 触摸按键与传统的机械按键相比&#xff0c;不仅美观而且耐用、寿命长&#xff0c;它颠覆了传统意义上的机械按键控制&#xff0c;只要轻轻触摸&#xff0c;就可以实现按键开关的控制、量化调节甚至方向控制。触摸按键已广泛应用于手机、DVD、洗衣机等消…

宿舍管理系统带文档java项目基于springboot+vue的宿舍管理系统

文章目录 宿舍管理系统一、项目演示二、项目介绍三、八千字项目文档四、部分功能截图五、部分代码展示六、底部获取项目源码和8000字论文参考&#xff08;9.9&#xffe5;带走&#xff09; 宿舍管理系统 一、项目演示 宿舍管理系统 二、项目介绍 基于springbootvue的前后端分…

MVC、MVP 和 MVVM 架构总结

MVC、MVP 和 MVVM 是常见的软件架构模式&#xff0c;主要用于组织应用程序的结构&#xff0c;特别是在用户界面和业务逻辑之间进行分离。以下是对它们的详细解释&#xff0c;包括它们的差异、优缺点。 MVC&#xff08;Model-View-Controller&#xff09; 结构 Model&#xf…

C++的继承(十一):私有继承和受保护的继承

但凡用过C的人都知道&#xff1a;私有继承的成员在派生类里均为私有&#xff0c;受保护的继承公有和受保护的成员在派生类里为受保护。另外C不对私有继承和受保护的继承的派生类指针自动转化为基础类。 #include <stdio.h> struct X {int a;X():a(9) {}int sqare() {ret…

5.nginx平滑升级

nginx平滑升级 一、nginx平滑升级1、下载新版本的安装包2、以之前的安装参数来编译新版本软件3、将新版本的nginx拷贝到安装目录4、启动新版本进程5、平缓关闭旧工作进程6、清理旧版本的nginx 一、nginx平滑升级 USR2 启动新版本进程 WINCH 平缓关闭旧工作进程 1、下载新版本…

分层注入的设计模式-上下层文件相互包含解决办法

现象&#xff1a;上下层文件相互包含 写代码时&#xff0c;会不会遇到&#xff0c;业务层内容要在底层硬件程序里写&#xff0c; 例如&#xff1a;一个外部按键&#xff0c;按键中断要触发一个应用层业务。 业务就要写道IO中断里&#xff0c;这个代码就要用到上层一些函数和变…

在长窗口时代,RAG技术是否仍然必要?

自从谷歌推出 Gemini 1.5 Pro&#xff0c;行业内部对于 RAG 的讨论就不绝于耳。 Gemini 1.5 Pro 的性能确实令人瞩目。根据谷歌公布的技术文档&#xff0c;该系统能够稳定处理长达 100 token 的内容&#xff0c;相当于一小时的视频、十一小时的音频、超过三万行的代码或七十万…

【VTKExamples::Utilities】第十七期 ZBuffer

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 公众号:VTK忠粉 前言 本文分享VTK样例ZBuffer,并解析接口vtkWindowToImageFilter,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力(^U^)ノ…

24 _ 分层和合成机制:为什么CSS动画比JavaScript高效?

在上一篇文章中我们分析了CSS和JavaScript是如何影响到DOM树生成的&#xff0c;今天我们继续沿着渲染流水线向下分析&#xff0c;来聊聊DOM树之后所发生的事情。 在前面《05 | 渲染流程&#xff08;上&#xff09;&#xff1a;HTML、CSS和JavaScript文件&#xff0c;是如何变成…

linux下can-utils的使用以及can接口的配置(以ubuntu20.04为例)

linux下can-utils的使用以及can接口的配置&#xff08;以ubuntu20.04为例&#xff09; can-utils是什么 can-utils 是一套用于Linux操作系统的开源工具&#xff0c;专门用来处理与CAN&#xff08;Controller Area Network&#xff09;总线相关的任务。CAN总线广泛应用于汽车和…

C语言文件操作:打开关闭,读写

程序文件 源程序文件&#xff08;后缀为.c&#xff09; 目标文件&#xff08;Windows环境后缀为.obj&#xff09; 可执行文件&#xff08;Windows环境后缀为.exe&#xff09; fputc FILE* pf fopen("test.txt","w");if (pf NULL){printf("%s\n"…

深入理解Qt计算器应用的构建过程

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、数字按钮的信号与槽函数连接 二、运算符按钮的信号与槽函数连接 三、特殊按钮的信号与…

红外超声波雷达测距(water)

文章目录 一 RS-232二 RS485三 Modbus四 stm32多路超声波测距4.1 设计方案4.2 代码 参考资料总结 实验要求 一. 采用stm32F103和HC-SR04超声波模块&#xff0c; 使用标准库或HAL库 定时器中断&#xff0c;完成1或2路的超声波障碍物测距功能。 1&#xff09;测试数据包含噪声&am…

Bezier Python 用法:深入探索与实用指南

Bezier Python 用法&#xff1a;深入探索与实用指南 在数字图形学和计算机编程中&#xff0c;贝塞尔曲线&#xff08;Bezier Curves&#xff09;是一种重要的参数曲线&#xff0c;被广泛应用于二维图形应用程序中&#xff0c;如字体轮廓、矢量图形和动画等。Python作为一种功能…

EukRep:区分真核和原核序列

https://github.com/patrickwest/EukRep 安装 conda create -y -n eukrep-env -c bioconda scikit-learn0.19.2 eukrep mamba install -c conda-forge numpy1.19.5 使用 EukRep -i <Sequences in Fasta format> -o <Eukaryote sequence output fasta file>