簡體   English   中英

無法使QSslSocket工作

[英]Can't get QSslSocket to work

我試圖在Qt中編寫一個簡單的客戶端-服務器應用程序,該應用程序將通過SSL通信。 我嘗試使用QSslSockets,但是仍然遇到各種問題。

看看這個:

客戶:

#define dumpvar(x) qDebug()<<#x<<'='<<x

int main(int argc, char** argv)
{
    QApplication a(argc, argv);

    QSslSocket s;
    auto cert = QSslCertificate::fromPath("/home/piotrek/cert.pem");
    Q_ASSERT(!cert.isEmpty());
    s.setCaCertificates({cert});
    s.connectToHostEncrypted("localhost", 1234);
    qDebug()<<"waiting for encrypted";
    if (!s.waitForEncrypted(10000)){
        dumpvar(s.errorString());
        dumpvar(s.sslErrors());
        return 0;
    }

    qDebug()<<"client connected";
}

服務器:

#define dumpvar(x) qDebug()<<#x<<'='<<x

class SslServer: public QTcpServer
{
    // QTcpServer interface
protected:
    void incomingConnection(qintptr handle) override
    {
        QSslSocket s;
        if (!s.setSocketDescriptor(handle)){
            dumpvar(s.errorString());
            return;
        }
        s.setLocalCertificate("/home/piotrek/cert.pem");
        s.setPrivateKey("/home/piotrek/pkey.pem", QSsl::Rsa, QSsl::Pem, "test");
        s.startServerEncryption();
        qDebug()<<"waiting for encrypted";
        if(!s.waitForEncrypted(10000)){
            dumpvar(s.errorString());
            dumpvar(s.sslErrors());
            return;
        }

        qDebug()<<"server encrypted";

        handleConnection(&s);
    }
};

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

    SslServer s;

    s.listen(QHostAddress::Any, 1234);
    return a.exec();
}

客戶端打印:

qt.network.ssl: QSslSocket: cannot resolve SSLv2_client_method
qt.network.ssl: QSslSocket: cannot resolve SSLv2_server_method
waiting for encrypted
<10 second pause>
s.errorString() = "Network operation timed out"
s.sslErrors() = ()

服務器打印:

qt.network.ssl: QSslSocket: cannot resolve SSLv2_client_method
qt.network.ssl: QSslSocket: cannot resolve SSLv2_server_method
waiting for encrypted
<10 second pause>
s.errorString() = "The remote host closed the connection"
s.sslErrors() = (

我究竟做錯了什么?

警告的解釋是Ubuntu中的OpenSSL編譯時沒有不安全的sslv2,但Qt 5.8嘗試在運行時加載這些功能。 Qt默認情況下僅使用安全協議,因此,除非您使用QSsl::SslV2顯式調用QSslSocket :: setProtocol ,否則這些警告不會對您造成影響(當然,這不適用於您的openssl)。

顯然您的自簽名有問題嗎? 證書 此外,除非使用主機簽名不匹配,否則使用自簽名證書進行連接都會失敗。

如果您使用的是自簽名證書,則可以按照此處的說明重新生成它們。

請在下面找到工作代碼示例。 在類似環境下測試( 令人驚訝!Ubuntu 16.10, OpenSSL 1.0.2g 1 Mar 2016, Qt 5.8.0

服務器

class SslServer: public QTcpServer
{
    // QTcpServer interface
protected:
    void incomingConnection(qintptr handle) override
    {
        QSslSocket s;
        if (!s.setSocketDescriptor(handle)){
            dumpvar(s.errorString());
            return;
        }
        const QString serverCertPath("/path/to/server1.pem");
        const QString serverKeyPath("/path/to/server1.key");
        s.setLocalCertificate(serverCertPath);
        s.setPrivateKey(serverKeyPath, QSsl::Rsa, QSsl::Pem, "test");
        s.startServerEncryption();
        qDebug()<<"waiting for encrypted";
        if(!s.waitForEncrypted(10000)){
            dumpvar(s.errorString());
            dumpvar(s.sslErrors());
            return;
        }
        qDebug()<<"server encrypted";
        s.write("Hello client");
        s.flush();
        s.waitForBytesWritten(3000);
        s.close();
    }
};

客戶

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

    QSslSocket s;
    const QString rootCAPath("/path/to/rootCA.pem");
    auto rootCACert = QSslCertificate::fromPath(rootCAPath);
    Q_ASSERT(!rootCACert.isEmpty());
    s.setCaCertificates(rootCACert);

    // ignore SSL host name mismatch error for server certificate
    QList<QSslError> errorsToIgnore;
    const QString serverCertPath("/path/to/server1.pem");
    auto serverCert = QSslCertificate::fromPath(serverCertPath);
    Q_ASSERT(!serverCert.isEmpty());
    errorsToIgnore<<QSslError(QSslError::HostNameMismatch, serverCert.at(0));
    s.ignoreSslErrors(errorsToIgnore);

    s.connectToHostEncrypted("localhost", 1234);
    qDebug()<<"waiting for encrypted";
    if (!s.waitForEncrypted(10000)){
        dumpvar(s.errorString());
        dumpvar(s.sslErrors());
        return 0;
    }
    qDebug()<<"client connected";
    s.waitForReadyRead(3000);
    qDebug() << "Reading: " << s.bytesAvailable();
    qDebug() << s.readAll();
    s.close();
}

服務器輸出:

qt.network.ssl: QSslSocket: cannot resolve SSLv2_client_method
qt.network.ssl: QSslSocket: cannot resolve SSLv2_server_method
waiting for encrypted
server encrypted

客戶輸出:

qt.network.ssl: QSslSocket: cannot resolve SSLv2_client_method
qt.network.ssl: QSslSocket: cannot resolve SSLv2_server_method
waiting for encrypted
client connected
Reading:  12
"Hello client"
Press <RETURN> to close this window...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM