首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不能让QSslSocket工作

不能让QSslSocket工作
EN

Stack Overflow用户
提问于 2017-03-29 14:56:40
回答 1查看 2.5K关注 0票数 1

我试图用Qt编写一个简单的客户端服务器应用程序,该应用程序将通过SSL进行组合。我试过使用QSslSockets,但一直存在各种各样的问题。

看一看这个:

客户端:

代码语言:javascript
复制
#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";
}

服务器:

代码语言:javascript
复制
#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();
}

客户打印:

代码语言:javascript
复制
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() = ()

服务器打印:

代码语言:javascript
复制
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() = (

我做错了什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-03-30 07:31:57

对这些警告的解释是,Ubuntu中的OpenSSL是在没有不安全sslv2的情况下编译的,但是QT5.8试图在运行时加载这些函数。Qt默认情况下只使用安全协议,因此这些警告不会影响您,除非您使用QSslSocket::setProtocol显式调用QSsl::SslV2 (当然,这与openssl不起作用)。

很明显,你的自我签名有什么问题吗?证书.此外,除非显式地忽略主机名不匹配,否则自签名证书的连接无论如何都会失败.

如果您使用的是自签名证书,则可以使用找到的这里指令重新生成它们。

请在下面的工作代码示例中找到。在类似的环境(惊喜!) Ubuntu 16.10, OpenSSL 1.0.2g 1 Mar 2016, Qt 5.8.0上进行测试。

服务器

代码语言:javascript
复制
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();
    }
};

客户端

代码语言:javascript
复制
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();
}

服务器输出:

代码语言:javascript
复制
qt.network.ssl: QSslSocket: cannot resolve SSLv2_client_method
qt.network.ssl: QSslSocket: cannot resolve SSLv2_server_method
waiting for encrypted
server encrypted

客户端输出:

代码语言:javascript
复制
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...
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43097149

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档