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.pswp.cn/bicheng/20010.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/20010.shtml
英文地址,請注明出處:http://en.pswp.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>