如何在Qt上使用TLS协议

How to use the TLS protocol on Qt?

本文关键字:TLS 协议 Qt      更新时间:2023-10-16

请给出服务器端使用TLS的示例。

现在我有以下代码:

#include <QCoreApplication>
#include "server.h"
int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);
    Server h;
    return a.exec();
}
///////////////////////////////////////
#ifndef SERVER_H
#define SERVER_H
#include <QTcpServer>
class Server : public QTcpServer {
    public:
    Server();
    void incomingConnection(int);
};
#endif // SERVER_H

///////////////////////////////////////////
#include "server.h"
#include <QSslSocket>
#include <QSslCertificate>
Server::Server() {
    if (!listen(QHostAddress::Any, 80)) {
        //error
    }
}
void Server::incomingConnection(int d) {
    QSslSocket * socket = new QSslSocket();
    if(socket->setSocketDescriptor(d)) {
        QString c, k;
        c = "site.crt";
        k = "site.key";
        socket->setLocalCertificate(c);
        socket->setPrivateKey(k);
        socket->startServerEncryption();
        if(socket->waitForEncrypted()) {
            if(socket->waitForReadyRead()) {
                socket->write(socket->readAll());
                socket->waitForBytesWritten();
                socket->disconnectFromHost();
                if(socket->state() == QTcpSocket::UnconnectedState) {
                    socket->waitForDisconnected();
                }
                socket->close();
                socket->deleteLater();
            }
            else {
                delete socket;
            }
        }
        else {
            delete socket;
        }
    }
}

如何将其更改为先使用协议TLS,然后使用SSL?

常见的任务是编写一个支持SNI的服务器。

下面是一个使用服务器的SSL或TLS服务器示例。密钥和服务器。CRT文件加密:

#include <QtNetwork>
#include <QMessageBox>
class server : public QTcpServer
{
    Q_OBJECT
public:
    explicit server(QObject *parent = 0);
    ~server();
    QSslSocket server_socket;
public slots:

      void tcpReady();
      void encrypted();
      void sslError( QList<QSslError> errors );
      bool start_listen(int port_no);
protected:
    void incomingConnection(qintptr descriptor );
};
server::server(QObject *parent) :
    QTcpServer(parent)
{
    server_socket.setProtocol(QSsl::AnyProtocol);
    QByteArray key;
    QByteArray cert;
    QFile file_key("server.key");
    if(file_key.open(QIODevice::ReadOnly))
    {
        key = file_key.readAll();
        file_key.close();
    }
    else
    {
        qDebug() << file_key.errorString();
    }
    QFile file_cert("server.crt");
    if(file_cert.open(QIODevice::ReadOnly))
    {
        cert = file_cert.readAll();
        file_cert.close();
    }
    else
    {
        qDebug() << file_cert.errorString();
    }

    QSslKey ssl_key(key, QSsl::Rsa,QSsl::Pem,QSsl::PrivateKey,"server");
    QSslCertificate ssl_cert(cert);
    server_socket.addCaCertificate(ssl_cert);
    server_socket.setLocalCertificate(ssl_cert);
    server_socket.setPrivateKey(ssl_key);

    connect( &server_socket, SIGNAL(sslErrors(QList<QSslError>)),
            this, SLOT(sslError(QList<QSslError>)) );
    connect(&server_socket,SIGNAL(encrypted()),this,SLOT(encrypted()));
    server_socket.setSocketOption(QAbstractSocket::KeepAliveOption, true );
}
server::~server()
{
    server_socket.disconnectFromHost();
    server_socket.waitForDisconnected();
}
void server::tcpReady()
{
    QByteArray array = server_socket.read( server_socket.bytesAvailable() );
    //...
}
void server::encrypted()
{
    connect( &server_socket, SIGNAL(readyRead()),
             this, SLOT(tcpReady()) );
    emit connection_established();
}
void server::sslError(QList<QSslError> errors)
{
    QString erroStr="";
    foreach (const QSslError &e, errors)
        erroStr.append(e.errorString()).append("n");
    QMessageBox::warning( (QWidget *)this->parent(), tr("Error"),erroStr );
    server_socket.ignoreSslErrors();
}

bool server::start_listen(int port_no)
{
    if( !this->listen( QHostAddress::Any, port_no ) )
    {
        QMessageBox::warning( (QWidget *)this->parent(), tr("Error!"), tr("Cannot listen to port %1").arg(port_no) );
    }
    else
        return true;
}
void server::incomingConnection(qintptr descriptor)
{
    if(server_socket.state()!=QAbstractSocket::UnconnectedState)
        return;
    if( !server_socket.setSocketDescriptor( descriptor ) )
    {
        QMessageBox::warning( (QWidget *)this->parent(), tr("Error!"), tr("Socket error!") );
        return;
    }
    else
    {
        server_socket.startServerEncryption();
    }
}

可以设置协议为QSsl::SslV3QSsl::TlsV1,只接受SSL或TLS连接。