当使用 Qt 进行 HTTPS 请求时,我尝试在 SSL 握手后获取对等方的证书,以便跟踪证书中的 future 更改。
QNetworkAccessManager nam;
nam.get(QNetworkRequest(QUrl("https://google.com/"))); // example URL
QObject::connect(&nam, &QNetworkAccessManager::encrypted, [](QNetworkReply *reply){
qDebug() << reply->sslConfiguration().peerCertificate();
});
根据documentation of QNetworkAccessManager::encrypted
,上面的代码应该可以访问服务器的证书:
This signal is emitted when an SSL/TLS session has successfully completed the initial handshake. At this point, no user data has been transmitted. The signal can be used to perform additional checks on the certificate chain, for example to notify users when the certificate for a website has changed. If the reply does not match the expected criteria then it should be aborted by calling QNetworkReply::abort() by a slot connected to this signal. The SSL configuration in use can be inspected using the QNetworkReply::sslConfiguration() method.
此外,来自 documentation of QSslConfiguration::peerCertificate()
:
Because the peer certificate is set during the handshake phase, it is safe to access the peer certificate from a slot connected to the QSslSocket::sslErrors() signal, QNetworkReply::sslErrors() signal, or the QSslSocket::encrypted() signal.
但是,证书总是空的。上述代码的调试输出(进入应用程序的事件循环后)是:
QSslCertificate( "" , "" , "1B2M2Y8AsgTpgAmY7PhCfg==" , () , () , QMap() , QDateTime(" Qt::LocalTime") , QDateTime(" Qt::LocalTime") )
另一方面,如果遇到 SSL 错误,并且如果我连接到 sslErrors
,我将 获取证书。例如,对于 Ubuntu/Apache 下的默认证书,由于证书中缺少主机名而未被 Qt 接受,我为 "https://localhost"
获取以下内容:
QSslCertificate( "3" , "95:b0:93:f2:16:bb:22:cb" , "cXB6WctE7oZsrvZLU2BWUw==" , () , () , QMap() , QDateTime("2014-07-10 23:04:06.000 UTC Qt::UTC") , QDateTime("2024-07-07 23:04:06.000 UTC Qt::UTC") )
SSL握手成功后如何获取证书?
我测试了 QNetworkAccessManager 的信号,以及 QNetworkReply 的信号;结果是一样的。
可以在 https://bitbucket.org/leemes/ssltest 找到 MCVE ,请随意克隆和摆弄:
git clone https://bitbucket.org/leemes/ssltest.git
我用 Qt 5.4.0 和 Qt 5.3.1 进行了测试;结果是一样的。
最佳答案
这是 Qt 5.4.0 之前的一个错误。它已在 Qt 5.4.1 中修复。
关于c++ - SSL握手成功后如何获取peer的QSslCertificate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28813884/