小工具知识网

当前位置: 首页 > 行业知识 > Windows C++下使用c++-httplib库与Openssl库搭建https服务器与客户端通讯的保姆教程

行业知识

Windows C++下使用c++-httplib库与Openssl库搭建https服务器与客户端通讯的保姆教程

2026-11-06 11:04:43 来源:互联网转载

Windows C++下使用c++-httplib库与Openssl库搭建https服务器与客户端通讯的保姆教程

    • 前言
    • c++ -httplib源码下载
    • Openssl源码下载编译
      • 1.openssl源码下载
      • 2.编译环境准备
        • 1)安装Perl
        • 2)安装NASM
        • 3)编译openssl
        • 使用Openssl生成本地CA证书用于搭建https本地测试通讯
          • 1.CA:
          • 2.服务器
          • 3.客户端
          • VS2015下c++项目实战
            • 1.Openssl在VS2015工程中的配置
            • 2.本地测试代码如下
            • 结语
            • tips

              前言

              实���一个c++的https客户端请求https服务器是实现数据通信 。

              基于已封装好的c++ -httplib库搭建SSL/TLS环境实现。

              c++ -httplib源码下载

              httplib库是一个基于C++11特性编写的库,所以编译器需要能支持C++11。

              c++ -httplib源码下载网址直接下载zip包

              此库的源代码只有一个头文件,所以在使用时只需在项目中包含一个头文件即可

              解压zip包的要用的头文件如下所示:

              Openssl源码下载编译

              1.openssl源码下载

              本人项目是基于为win32环境的x86编译,环境都是安装的win32版本,如是win64版本请另行下载各自对应的版本

              openssl源码下载路径我下载的是openssl-1.1.1v.tar.gz可以使用,所以推荐下载此版本

              若想下载旧版本,则点击old releases获取即可

              2.编译环境准备

              openssl官网下载的源码中没找到现成的dll和lib文件,在这里我选择自己编译生成想要的版本库,解压如下:

              1)安装Perl

              搜索网络上有的下载的是ActiveState Perl,但是极其麻烦,我弄半天也没下载成功,在此所以推荐下载草莓Perl

              下载地址: Windows版本Strawberry Perl

              下载好自己的版本,我这里下的是32位的,如下

              一般下载安装后会自动添加perl的三个环境变量:

              建议安装后还是检查一下,万一没有则手动添加即可。

              cmd命令行输入perl -v查看是否安装成功:

              2)安装NASM

              官网下载路径

              下载完运行这个exe安装即可,注意这里安装完也要对环境变量进行检查,我就是没检查,然后后面在编译openssl中编译到一半,说我编译环境错误,当时头痛的很,后面全部重新安装了一遍,手动添加了这个环境变量。

              这里变量为你安装NASM的路径,鼠标右击nasm属性查看路径如下:

              3)编译openssl

              windows所有程序打开vs2015开发人员命令提示应用,我的开发环境是vs2015,vs你们使用自己的版本即可

              在此cmd窗口中进入到刚刚下载解压的openssl源码路径下,

              命令行输入perl Configure VC-WIN32 --shared no-asm --debug --prefix=C:\Common-Test\openSSL --openssldir=C:\Common-Test\SSL

              具体参数配置在openssl源码解压的目录下有个 INSTALL 文件可以看到

              32位:VC-WIN32

              64位:VC-WIN64A

              编译生成动态库Dll:–shared (不生成则使用no-shared,默认不生成)

              不使用汇编代码:no-asm

              Debug:–debug

              Release:–release(默认)

              最后安装的目录:–prefix=C:\Common-Test\openSSL

              一些配置说明文件存放目录:–openssldir=\Common-Test\SSL

              然后依次输入

              nmakenamke testnmake installnmake clean  //这里是清除生成的多余文件

              等待三个命令运行完成。

              注意:中途万一编译失败,请重新安装以上环境并检查环境变量是否存在

              在我们的输出安装目录下可以看到以下四个文件夹

              静态库lib文件在lib目录下,

              头文件在include目录下,

              动态库dll文件在bin目录下,在启动运行的时候会用到。这个放在程序启动的那个目录就行了,

              至此,win32系统的openssl编译库完成(其他的版本环境的编译步骤与这个是一致的),下面就可以运用到项目中了。

              ————————————————

              使用Openssl生成本地CA证书用于搭建https本地测试通讯

              本地开发https服务是加密的,这里使用openssl自签名证书,并使用基于c+±httplib开启https服务。

              在创建证书的过程中,会要求输入密码和证书信息(浏览器地址左侧有一个锁,点开后选择证书看到的信息),密码在输入过程中,控制台不会有任何显示。输入信息需要填写国家(ZH)、省市、机构等信息,由于自己签名并没有公网的可认证性,所以这些信息随便填都可以。后面会要求输入密码生成证书,所以需要记住密码。

              1.CA:

              生成私钥:这里的1024也可改为2048,指复杂度

              openssl genrsa -out ca-key.pem -des 1024

              这里我设的密码是123456,自己随便设。

              生成公钥:

              openssl req -new -key ca-key.pem -out ca-csr.pem

              生成证书:

              openssl x509 -req -in ca-csr.pem -signkey ca-key.pem -out ca-cert.pem

              在当前路径下会有 ca-key.pem 、 ca-csr.pem、 ca-cert.pem三个文件,如果其中有步骤出现失误操作,将这些指令重新输入即可

              2.服务器

              服务端生成公钥需要读取配置文件,创建openssl.cnf文件在统计目录下,内容为:

              [req]            distinguished_name = req_distinguished_name            req_extensions = v3_req                    [req_distinguished_name]            countryName = ZH            countryName_default = CN            stateOrProvinceName = ShenZhen          stateOrProvinceName_default = ShenZhen           localityName = GuangZhou            localityName_default = GuangZhou            organizationalUnitName  = public section            organizationalUnitName_default  = Domain Control Validated            commonName = Internet Widgits Ltd            commonName_max  = 64                    [ v3_req ]            # Extensions to add to a certificate request            basicConstraints = CA:FALSE            keyUsage = nonRepudiation, digitalSignature, keyEncipherment            subjectAltName = @alt_names                    [alt_names]            IP.1 = 127.0.0.1

              上述信息是证书相关的信息,后面的值都是随意写的,可以自己替换。

              也可以直接把C:\Common-Test\SSL目录下的openssl.cnf文件拷贝过来

              生成私钥:

              openssl genrsa -out server-key.pem 1024

              生成公钥:

              openssl req -new -key server-key.pem -config openssl.cnf -out server-csr.pem

              生成证书:

              openssl x509 -req -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -in server-csr.pem -out server-cert.pem -extensions v3_req -extfile openssl.cnf

              3.客户端

              搭建https服务器不需要客户端证书,生成指令和上面类似:

              openssl genrsa -out client-key.pem

              生成公钥:

              openssl req -new -key client-key.pem -out client-csr.pem

              生成证书:

              openssl x509 -req -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -in client-csr.pem -out client-cert.pem

              最终生成文件如下所示:

              这里我没用到客户端的证书就没生成了,你们可以自己生成。

              VS2015下c++项目实战

              1.Openssl在VS2015工程中的配置

              这里的lib也可以在代码中加载,如#pragma comment(lib, “libcrypto.lib”)。

              2.本地测试代码如下

              自己懒得写了,这里是引用的是

              Jinato2016大佬的代码

              服务器代码:

              #include "stdafx.h"#include #include #include #include #include #include #include #include #include #include #include "httplib.h"#define SERVER_CERT_FILE "C:\\Common-Test\\openSSL\\bin\\server-cert.pem"#define SERVER_PRIVATE_KEY_FILE "C:\\Common-Test\\openSSL\\bin\\server-key.pem"#pragma comment(lib, "WS2_32.lib")#define MAXBUF 1024using namespace std;using namespace httplib;std::string dump_headers(const Headers &headers) {std::string s;char buf[BUFSIZ];for (auto it = headers.begin(); it != headers.end(); ++it) {const auto &x = *it;snprintf(buf, sizeof(buf), "%s: %s\n", x.first.c_str(), x.second.c_str());s += buf;}return s;}std::string log(const Request &req, const Response &res) {std::string s;char buf[BUFSIZ];s += "================================\n";snprintf(buf, sizeof(buf), "%s %s %s", req.method.c_str(),req.version.c_str(), req.path.c_str());s += buf;std::string query;for (auto it = req.params.begin(); it != req.params.end(); ++it) {const auto &x = *it;snprintf(buf, sizeof(buf), "%c%s=%s",(it == req.params.begin()) ? '?' : '&', x.first.c_str(),x.second.c_str());query += buf;}snprintf(buf, sizeof(buf), "%s\n", query.c_str());s += buf;s += dump_headers(req.headers);s += "--------------------------------\n";snprintf(buf, sizeof(buf), "%d %s\n", res.status, res.version.c_str());s += buf;s += dump_headers(res.headers);s += "\n";if (!res.body.empty()) { s += res.body; }s += "\n";return s;}void custom_error_handler(const Request& req, Response& res) {// 自定义错误处理逻辑//res.status = 500;//res.set_content("Custom Error Handler: Something went wrong!", "text/plain");const char *fmt = "

              Error Status: %d

              ";char buf[BUFSIZ];snprintf(buf, sizeof(buf), fmt, res.status);res.set_content(buf, "text/html");}int main(void) {SSLServer svr(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE);cout printf("server has an error...\n");return -1;}svr.Get("/", [=](const Request & /*req*/, Response &res) {res.set_redirect("/hi");});svr.Get("/hi", [](const Request & /*req*/, Response &res) {res.set_content("

上一篇:python如何在一个py文件中运行另一个py文件的代码

下一篇:drink怎么读语音?