将C++搭建的简单HTTP服务器升级为 HTTPS 服务器

HTTP 协议是不加密的,容易遭受中间人攻击(MITM)。为了提高安全性,你可以将服务器升级为 HTTPS 服务器,使用 SSL/TLS 加密流量。下面是如何将以下链接文章中的 HTTP 服务器修改为 HTTPS 服务器的步骤:

ps:使用C++构建一个简单的HTTP服务器,处理请求和响应_html请求 c++服务端-CSDN博客

使用 OpenSSL 生成自签名证书

首先,你需要生成自签名证书。以下是一个简单的命令:

复制代码
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes

这个命令会生成一个有效期为 365 天的自签名证书 (cert.pem) 和私钥文件 (key.pem)。

修改服务器代码以支持 HTTPS

接下来,修改你的服务器代码以使用 QSslSocketQSslConfiguration 来支持 HTTPS。

复制代码
#include <QCoreApplication>
#include <QTcpServer>
#include <QSslSocket>
#include <QDebug>
#include <QTextStream>
#include <QSslConfiguration>
#include <QSslKey>
#include <QSslCertificate>

class HttpsServer : public QTcpServer {
    Q_OBJECT

public:
    HttpsServer(QObject *parent = nullptr) : QTcpServer(parent) {
        // 加载证书和私钥
        QFile certFile("cert.pem");
        QFile keyFile("key.pem");
        if (!certFile.open(QIODevice::ReadOnly) || !keyFile.open(QIODevice::ReadOnly)) {
            qCritical() << "Failed to open certificate or key file.";
            return;
        }
        QSslCertificate certificate(&certFile, QSsl::Pem);
        QSslKey privateKey(&keyFile, QSsl::Rsa, QSsl::Pem);
        certFile.close();
        keyFile.close();

        sslConfig.setLocalCertificate(certificate);
        sslConfig.setPrivateKey(privateKey);
        sslConfig.setPeerVerifyMode(QSslSocket::VerifyNone); // 这里设置为 VerifyNone 仅用于测试
    }

protected:
    void incomingConnection(qintptr socketDescriptor) override {
        QSslSocket *socket = new QSslSocket(this);
        if (socket->setSocketDescriptor(socketDescriptor)) {
            socket->setSslConfiguration(sslConfig);
            socket->startServerEncryption();
            connect(socket, &QSslSocket::encrypted, this, &HttpsServer::handleConnection);
            connect(socket, &QSslSocket::disconnected, socket, &QSslSocket::deleteLater);
        } else {
            qWarning() << "Failed to set socket descriptor.";
            delete socket;
        }
    }

private slots:
    void handleConnection() {
        QSslSocket *socket = qobject_cast<QSslSocket *>(sender());
        if (!socket) return;

        connect(socket, &QSslSocket::readyRead, this, &HttpsServer::handleRequest);
    }

    void handleRequest() {
        QSslSocket *socket = qobject_cast<QSslSocket *>(sender());
        if (!socket) return;

        QTextStream in(socket);
        QString request = in.readAll();

        qDebug() << "Received encrypted request:\n" << request;

        // 构建 HTTP 响应
        QString response = "HTTP/1.1 200 OK\r\n";
        response += "Content-Type: text/html; charset=UTF-8\r\n";
        response += "\r\n";
        response += "<html><body><h1>Hello, World!</h1></body></html>";

        // 发送响应
        QTextStream out(socket);
        out << response;
        socket->flush();
        socket->close();
    }

private:
    QSslConfiguration sslConfig;
};

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    HttpsServer server;
    if (!server.listen(QHostAddress::Any, 443)) { // 使用 443 端口
        qCritical() << "Unable to start the server:" << server.errorString();
        return 1;
    }

    qDebug() << "Listening on port 443...";

    return a.exec();
}

#include "main.moc"

关键修改点

  1. 使用 QSslSocket 代替 QTcpSocket

    • QSslSocketQTcpSocket 的扩展,支持加密通信。
    • incomingConnection 方法中,使用 QSslSocket 设置 Socket 描述符,并启动 SSL 加密。
  2. 加载证书和私钥

    • 在构造函数中加载证书 (cert.pem) 和私钥 (key.pem) 文件,并设置 SSL 配置。
    • sslConfig.setLocalCertificatesslConfig.setPrivateKey 用于设置证书和私钥。
  3. 修改监听端口

    • 将监听端口从 80 修改为 443,这是 HTTPS 的标准端口。
  4. 处理加密连接

    • incomingConnection 中,调用 socket->startServerEncryption() 启动加密。
    • 连接 QSslSocket::encrypted 信号到 handleConnection 槽,确保数据在加密状态下读取。

运行服务器

确保你的证书 (cert.pem) 和私钥文件 (key.pem) 在可执行文件的同一目录下,然后编译并运行服务器。服务器现在将监听 443 端口,并使用 SSL/TLS 加密流量,从而提高安全性,防止中间人攻击。

相关推荐
fengyehongWorld18 分钟前
Linux sudo命令
linux·运维·服务器
WG_1725 分钟前
Linux:缓冲区_glibc封装
linux·运维·服务器
番知了27 分钟前
Ubuntu 22.04 常用命令清单
linux·运维·ubuntu
旺仔Sec30 分钟前
2026年河北省职业院校技能大赛“网络系统管理”(高职组)网络构建样题
运维·服务器·网络
FF-Studio1 小时前
Ubuntu 24.04 磁盘爆满“灵异“事件:Btrfs, Snapper 与删不掉的空间
linux·运维·人工智能·ubuntu
爱尔兰极光1 小时前
计算机网络--网络层
运维·服务器·计算机网络
Neolnfra1 小时前
Xshell SSH 连接故障排查
运维·服务器·网络·ssh·xshell·运程连接
MonkeyKing_sunyuhua1 小时前
ubuntu22.04安装nginx
运维·windows·nginx
Joren的学习记录2 小时前
【Linux运维大神系列】Docker详解(二)
linux·运维·docker
Fortune_yangyang2 小时前
Docker 入门指南:从 “容器小白” 到快速上手
运维·docker·容器