繁体   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