c++ - 尝试连接自签名证书时出现 QT 5.5 SSLHandshakeFailedError

标签 c++ qt network-programming ssl-certificate

我使用以下代码尝试建立与远程主机的连接。

客户端必须使用自签名证书进行身份验证才能创建有效的 SSL 连接:

QRemoteProxyCommunication::QRemoteProxyCommunication(QObject *parent) : QObject(parent) {
    QNetworkAccessManager *manager = new QNetworkAccessManager(this);

    QNetworkRequest request;

    QFile certFile("/path/to/file/clientcert.p12");
    certFile.open(QFile::ReadOnly);
    QSslCertificate certificate;
    QSslKey key;
    QList<QSslCertificate> importedCerts;

    bool imported = QSslCertificate::importPkcs12(&certFile, &key, &certificate, &importedCerts, QByteArray::fromStdString(""));
    qDebug() << "Imported: " << imported;

    QSslConfiguration config = request.sslConfiguration();

    config.setCaCertificates(importedCerts);
    config.setProtocol(QSsl::AnyProtocol);
    config.setPeerVerifyMode(QSslSocket::VerifyNone);
    request.setSslConfiguration(config);
    request.setUrl(QUrl("https://www.url.com"));
    reply = manager->get(request);;

    qDebug() << " Certs: " << certificate;

    qDebug() << reply->error();
    qDebug() << reply->errorString();

    connect(reply, SIGNAL(readyRead()), this, SLOT(replyReadyRead()));
    connect(reply, SIGNAL(finished()), this, SLOT(replyFinished()));
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(replyNetworkError(QNetworkReply::NetworkError)));
    connect(manager, SIGNAL(sslErrors(QNetworkReply*, const QList<QSslError>)),
            this, SLOT(errors(QNetworkReply*, const QList<QSslError>)));
    connect(manager, SIGNAL(sslErrors(QNetworkReply*, const QList<QSslError>)),
            this, SLOT(errors(QNetworkReply*, const QList<QSslError>)));

}

void QRemoteProxyCommunication::replyNetworkError(QNetworkReply::NetworkError code) {

    qDebug() << "Network error => " << code;
}

但我总是收到错误信息:

网络错误 => QNetworkReply::NetworkError(SslHandshakeFailedError)replyNetworkError SLOT 中。

此外,插槽 errors 不会被调用。

QSslCertificate::importPkcs12(&certFile, &key, &certificate, &importedCerts, QByteArray::fromStdString("")); 返回 true

如果我在 Chrome 浏览器中添加 p12 证书文件并尝试打开主机,它工作正常。

此外,如果我尝试调用 request.setUrl(QUrl("https://www.test.de")); 将调用 readyRead() 信号我可以阅读响应内容。

我的实现有什么问题?

最佳答案

问题是在 importPkcs12 函数中作为参数传递的引用对象(如 QSslKey)没有在 QSslConfiguration 中明确设置配置对象。

QFile certFile("/path/to/file/clientcert.p12");
certFile.open(QFile::ReadOnly);
QSslCertificate certificate;
QSslKey key;
QList<QSslCertificate> importedCerts;

bool imported = QSslCertificate::importPkcs12(&certFile, &key, &certificate, &importedCerts, QByteArray::fromStdString("xxxx"));

QSslConfiguration config = request.sslConfiguration();

config.setCaCertificates(importedCerts);
config.setLocalCertificate(certificate);
config.setPrivateKey(key);
config.setProtocol(QSsl::AnyProtocol);
config.setPeerVerifyMode(QSslSocket::VerifyNone);

添加缺失的线路后,连接成功建立。

关于c++ - 尝试连接自签名证书时出现 QT 5.5 SSLHandshakeFailedError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37326952/

相关文章:

c++ - 在 QT 中获取窗口 WIds 列表

qt - Qt中如何快速下载大文件

linux - 零拷贝机制和 libpcap

linux - 如何在 Rust 中设置套接字选项 SO_REUSEPORT?

android - 如何解决 Android 上的 TCP/UDP 数据包 fragment 问题

c++ - 套接字通过并发FTP传输接收到错误的数据

c++ - 它是一个 gdb 错误吗?

c++ - 返回对象或 NULL 的返回类型

c++ - Qt- Qlist 检查包含自定义类

c++ - Boost Spirit Parser 可选表达式求值