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
接下来,修改你的服务器代码以使用 QSslSocket
和 QSslConfiguration
来支持 HTTPS。
#include <QCoreApplication>
#include <QTcpServer>
#include <QSslSocket>
#include <QDebug>
#include <QTextStream>
#include <QSslConfiguration>
#include <QSslKey>
#include <QSslCertificate>class HttpsServer : public QTcpServer {Q_OBJECTpublic: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"
关键修改点
-
使用
QSslSocket
代替QTcpSocket
:QSslSocket
是QTcpSocket
的扩展,支持加密通信。- 在
incomingConnection
方法中,使用QSslSocket
设置 Socket 描述符,并启动 SSL 加密。
-
加载证书和私钥:
- 在构造函数中加载证书 (
cert.pem
) 和私钥 (key.pem
) 文件,并设置 SSL 配置。 sslConfig.setLocalCertificate
和sslConfig.setPrivateKey
用于设置证书和私钥。
- 在构造函数中加载证书 (
-
修改监听端口:
- 将监听端口从 80 修改为 443,这是 HTTPS 的标准端口。
-
处理加密连接:
- 在
incomingConnection
中,调用socket->startServerEncryption()
启动加密。 - 连接
QSslSocket::encrypted
信号到handleConnection
槽,确保数据在加密状态下读取。
- 在
运行服务器
确保你的证书 (cert.pem
) 和私钥文件 (key.pem
) 在可执行文件的同一目录下,然后编译并运行服务器。服务器现在将监听 443 端口,并使用 SSL/TLS 加密流量,从而提高安全性,防止中间人攻击。