【问题标题】:QNetworkRequest with ssl local certificate带有 ssl 本地证书的 QNetworkRequest
【发布时间】:2011-11-22 07:15:45
【问题描述】:

我需要与需要本地证书(.crt 文件)的服务器交换数据。 我试试这个:

loginRequest = QNetworkRequest(QUrl("https://somesite.com/login"));

QSslConfiguration sslConf = loginRequest.sslConfiguration();
QList<QSslCertificate> certs = QSslCertificate::fromPath(Preferences::certificatePath());
qDebug() << certs.first().issuerInfo(QSslCertificate::Organization); // prints name
sslConf.setLocalCertificate(certs.first());
qDebug() << "is valid " << sslConf.localCertificate().isValid(); // true
qDebug() << "is null " << sslConf.localCertificate().isNull(); // false
qDebug() << "protocol " << sslConf.protocol(); // 0
sslConf.setProtocol(QSsl::SslV3); // i also tried Qssl::AnyProtocol
qDebug() << "protocol " << sslConf.protocol(); // 0

// if i uncomment these i expect everithing to work
//QSslConfiguration::setDefaultConfiguration(sslConf);
//QSslSocket::addDefaultCaCertificate(certs.first());
//loginRequest.setSslConfiguration(sslConf);

QObject::connect(connectionManager, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)), this, SLOT(printSslErrors2(QNetworkReply*,QList<QSslError>)));

m_reply = connectionManager->get(loginRequest);
QObject::connect(m_reply, SIGNAL(readyRead()), this, SLOT(getCookie()));
QObject::connect(m_reply, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(printSslErrors(QList<QSslError>)));

当此代码执行时,我在 WireShark 中有以下消息(过滤器:tcp && ssl && ip.addr == my_addr):

Client Hello
ServerHello, Certificate
Server Key Exchange, Certificate request, Server Hello Done
Alert (level: Warning, Description: no certificate), client key exchange, change cipher spec, encrypted handshake message
Alert (level: Fatal, Description: Handshake failure)

这是意料之中的——应用证书的代码被注释掉了,但奇怪的是——我的 QNetworkAccessManager 和 QNetworkReply 没有收到任何 ssl 错误(插槽 printSslErrors 和 printSslErrors2)。

如果我取消注释这 3 行中的任何一行:

 //QSslConfiguration::setDefaultConfiguration(sslConf);
 //QSslSocket::addDefaultCaCertificate(certs.first());
 //loginRequest.setSslConfiguration(sslConf);

我在 wireshark 中什么都没有(SYN、ACK 和 FIN tcp 消息很少,但没有 http 或 ssl 流量)。 QNetworkAccessManager 和 QNetworkReply 仍然没有错误,所以我不知道出了什么问题。

有没有机会让 Qt 接受我的本地证书,或者可能有一些面向 3d 方 qt 的库来帮助我?

P.S.:顺便说一句 - ssl 和 https 几天前工作得很好,在服务器被更改为需要客户端证书之前。

P.P.S.:如果有任何区别,证书是自签名的。我还尝试将它(p12 文件)“安装”到系统中,Chrome 和 IE7 都可以使用它并与服务器通信。

【问题讨论】:

    标签: c++ certificate openssl qnetworkaccessmanager qt4.7


    【解决方案1】:

    在黑暗中完成拍摄并假设 Qt 实际上可能正在报告错误但您没有收到信号。

    您正在将信号从您的connectionManager 连接到this 您是否在this 的标头中包含了Q_OBJECT 宏?

    在运行应用程序时还要检查输出,因为如果此处确实是这种情况,Qt 可能会报告连接信号/插槽的问题。

    【讨论】:

    • 1.这是一个 QMainWindow,它从登录按钮获取信号(这个启动登录序列)所以我不明白为什么其他信号可能会被忽略 2. 信号/插槽没有错误。我知道的唯一错误(在应用程序输出窗口中报告)是关于信号和插槽不存在或参数错误
    • 如果您将其他信号输入 QMainWindow 类,那就太好了。检查 Q_OBJECT 宏是我遇到麻烦时做的第一件事。希望你能找到真正的问题。
    【解决方案2】:

    解决方案,第一部分: 我主要解决了这个问题(缺乏连接),有两个原因:

    1st - apache 服务器实际上需要私钥(由于某些未知原因,在 [here][1] 找到它),如何添加私钥:

    QFile x(Preferences::certificateKeyPath()); 
    x.open(QIODevice::ReadOnly);
    pKey = QSslKey(x.readAll(),QSsl::Rsa);
    QSslError error1(QSslError::SelfSignedCertificate, certs.first());
    QSslError error2(QSslError::CertificateUntrusted, certs.first());
    QList<QSslError> expectedSslErrors;
    expectedSslErrors.append(error1);
    expectedSslErrors.append(error2);
    

    2d - 我的证书不是很“好”。我不知道它的真正含义或为什么它不起作用,但是当我从服务器管理员那里获得新证书并添加私钥时,握手成功了。

    我仍然不知道如何捕捉 sslErrors(例如向用户显示他的证书不起作用),但这是一个好的开始

    解决方案,第二部分:

    解决了问题的最后一部分(kina a woraround)。似乎 QNetworkReply 没有发出 SslErrors 是一个错误(或者至少它不是一直有效或不适用于所有网站),在 [Qt bug tracker][2] 中发现了它。并且解决方法也从那里开始:我们无法获得 SslErrors,我们必须尝试获得 smth else - [error] [3],例如。它没有提供有关实际发生的事情的详细信息,但总比没有好。对我来说,错误代码 6 -“SSL/TLS 握手失败,无法建立加密通道。应该发出 sslErrors() 信号。”是完美的(我不在乎其他):

     QObject::connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(handleSslErrors(QNetworkReply::NetworkError)));
    

    重要的部分:如果用户有错误的证书和/或密钥 - 发出信号。但如果证书和密钥正确,也会发出它。似乎 auth 可能仍然不完美,但您可以使用

    轻松将其关闭
    QObject::connect(m_reply, SIGNAL(sslErrors(QList<QSslError>)), 
                      this, SLOT(printSslErrors(QList<QSslError>)));
    

    结论看来他们已经修复了Qt 4.8中的很多SSL错误,所以我希望尽快发布

    【讨论】:

      猜你喜欢
      • 2013-10-28
      • 1970-01-01
      • 1970-01-01
      • 2016-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-18
      相关资源
      最近更新 更多