简体   繁体   English

TLS 初始化失败和 SSL 握手失败 QtNetwork

[英]TLS initialization failed and SSL handshake failed QtNetwork

I'm using QtNetwork, QNetworkAccessManager, QNetworkRequest, QNetworkReply to set up a modal dialog to download any file provided in the URL path.我正在使用QtNetwork, QNetworkAccessManager, QNetworkRequest, QNetworkReply设置模式对话框以下载 URL 路径中提供的任何文件。

When I start the download, I get an error saying either Download failed: TLS initialization or ``Download failed: SSL handshake failed`, depending on different machines I test this on.当我开始下载时,我收到一条错误消息,提示Download failed: TLS initialization或“下载失败:SSL 握手失败”,具体取决于我测试的不同机器。

This seems to be an OpenSSL issue.这似乎是一个 OpenSSL 问题。 Is there a way to fix the error without requiring the user machine to have OpenSSL installed?有没有办法在不需要用户机器安装 OpenSSL 的情况下修复错误?

This is my download class这是我的下载 class

fAppDownloadDialog::fAppDownloadDialog()
{
  // set up UI modal dialog
  // ...
  // ...

  connect(cancelButton, SIGNAL(clicked()), this, SLOT(CancelButtonPressed()));
  connect(confirmButton, SIGNAL(clicked()), this, SLOT(ConfirmButtonPressed()));
}

void fAppDownloadDialog::CancelButtonPressed()
{
    this->close();
}

void fAppDownloadDialog::ConfirmButtonPressed()
{
    manager = new QNetworkAccessManager(this);

    QFileInfo fileInfo(url.path()); // QUrl url defined in .h
    QString fileName = fileInfo.fileName(); 

    fullPath = downloadPath + fileName; // QString fullPath, downloadPath in .h

    if (QFile::exists(fullPath)) {
        if (QMessageBox::question(this, tr("HTTP"),
                tr("There already exists a file %1. Overwrite?").arg(fileName),
                QMessageBox::Yes|QMessageBox::No, QMessageBox::No)
                == QMessageBox::No)
                return;
        QFile::remove(fullPath);
    }

    file = new QFile(fullPath); // QFile file in .h
    if (!file->open(QIODevice::WriteOnly)) {
        QMessageBox::information(this, tr("HTTP"),
                    tr("Unable to save the file %1: %2")
                    .arg(fileName).arg(file->errorString()));
        delete file;
        file = 0;
        return;
    }

    // used for progressDialog
    // This will be set true when canceled from progress dialog
    httpRequestAborted = false;

    startRequest(url);

    this->close();
}

// This will be called when download button is clicked
void fAppDownloadDialog::startRequest(QUrl url)
{
    // get() method posts a request
    // to obtain the contents of the target request
    // and returns a new QNetworkReply object
    // opened for reading which emits
    // the readyRead() signal whenever new data arrives.
    reply = manager->get(QNetworkRequest(url));

    // Whenever more data is received from the network,
    // this readyRead() signal is emitted
    connect(reply, SIGNAL(readyRead()),
            this, SLOT(httpReadyRead()));

    // This signal is emitted when the reply has finished processing.
    // After this signal is emitted,
    // there will be no more updates to the reply's data or metadata.
    connect(reply, SIGNAL(finished()),
            this, SLOT(httpDownloadFinished()));
}


void fAppDownloadDialog::httpReadyRead()
{
    // this slot gets called every time the QNetworkReply has new data.
    // We read all of its new data and write it into the file.
    // That way we use less RAM than when reading it at the finished()
    // signal of the QNetworkReply
    if (file)
        file->write(reply->readAll());
}

// When download finished or canceled, this will be called
void fAppDownloadDialog::httpDownloadFinished()
{
  // when canceled
    if (httpRequestAborted) {
        if (file) {
            file->close();
            file->remove();
            delete file;
            file = 0;
        }
        reply->deleteLater();

        return;
    }

    // download finished normally
    file->flush();
    file->close();

    // get redirection url
    QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
    if (reply->error()) {
        file->remove();
        QMessageBox::information(this, tr("HTTP"),
                                tr("Download failed: %1.")
                                .arg(reply->errorString()));
    } else if (!redirectionTarget.isNull()) {
        QUrl newUrl = url.resolved(redirectionTarget.toUrl());
        if (QMessageBox::question(this, tr("HTTP"),
                                tr("Redirect to %1 ?").arg(newUrl.toString()),
                                QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
            url = newUrl;
            reply->deleteLater();
            file->open(QIODevice::WriteOnly);
            file->resize(0);
            startRequest(url);
            return;
        }
    } else {
        QString fileName = QFileInfo(QUrl(qInputLink).path()).fileName();

    }

    reply->deleteLater();
    reply = 0;
    delete file;
    file = 0;
    manager = 0;
}

// During the download progress, it can be canceled
void fAppDownloadDialog::cancelDownload()
{
    httpRequestAborted = true;
    reply->abort();

    this->close();
}

You need to provide libssl and libcrypto libraries for your application.您需要为您的应用程序提供 libssl 和 libcrypto 库。

If you have installed Qt with Qt Installer on Windows, run Qt's Maintainer Tools and install OpenSSL Toolkit:如果您在 Windows 上安装了 Qt 和 Qt 安装程序,请运行 Qt 的维护者工具并安装 ZEE302FD5FD2A7A9793C19FC5BE21C Toolkit:

在此处输入图像描述

then copy ssl and crypto dll's right to the place where your app.exe file placed.然后将 ssl 和 crypto dll 的权限复制到您的 app.exe 文件所在的位置。 Dll's could be found in QTSDK root subfolder Tools\OpenSSL\Win_x64\bin Dll 可以在 QTSDK 根子文件夹 Tools\OpenSSL\Win_x64\bin 中找到

在此处输入图像描述

On linux just install/compile OpenSSL and link.so's to the right place在 linux 上,只需将 OpenSSL 和 link.so 安装/编译到正确的位置

Adding OpenSSL Support添加 OpenSSL 支持

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Qt&SSL,握手失败 - Qt & SSL, Handshake failed GET 请求上的 TLS 初始化失败 - TLS initialization failed on GET Request Qt 错误消息“qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS 初始化失败” - Qt error message “qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed” 与Qt 5.2.1上写的SSL服务器的SSL握手失败 - Failed SSL handshake with ssl server written on Qt 5.2.1 BB10 QNX Momentics IDE中的SSL握手失败 - SSL Handshake Failed in BB10 QNX Momentics IDE Websocket++ 错误:handle_transport_init 收到错误:TLS 握手失败 - Websocket++ error: handle_transport_init received error: TLS handshake failed 握手失败:证书验证失败(Boost ASIO) - Handshake failed: certificate verify failed (Boost ASIO) 静态编译 Qt 5.13.1 与 OpenSSL 1.1.1d 产生 QSslSocket::connectToHostEncrypted: TLS 初始化失败 - Statically compiled Qt 5.13.1 with OpenSSL 1.1.1d producing QSslSocket::connectToHostEncrypted: TLS initialization failed 尝试从C ++运行https代码时SSL握手失败 - SSL handshake failed when trying to run https code from c++ 握手失败,出现致命错误 SSL_ERROR_SSL:错误:100000f7:SSL 例程:OPENSSL_internal:WRONG_VERSION_NUMBER - Handshake failed with fatal error SSL_ERROR_SSL: error:100000f7:SSL routines:OPENSSL_internal:WRONG_VERSION_NUMBER
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM