c++ - SSL握手成功后如何获取peer的QSslCertificate

标签 c++ qt ssl https qnetworkaccessmanager

当使用 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 中修复。

https://bugreports.qt.io/browse/QTBUG-40401

关于c++ - SSL握手成功后如何获取peer的QSslCertificate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28813884/

相关文章:

qt - QML CheckBox 设置文本大小

ssl - Nginx 提供另一个站点的 SSL 证书

ssl - 启用 have_ssl mariadb 时遇到问题

c++ - 在对象上调用非常量成员函数指针

C++11 标准::数组

c++ - 拥有大量重载的类构造函数是否被认为是不好的编程实践?

c++ - 将引用 qplaintextedit 发送到 C++ 构造函数类

c++ - C++ 中的简单 'database'

linux - Qtcreator 中的调试助手在 Linux 上不起作用

ssl - 我应该在 Google Cloud 上为 Kubernetes 使用 Ingress 还是 LoadBalancer(带有自定义域和 SSL 证书)?