2015-03-02 71 views
4

使用Qt進行HTTPS請求時,我試圖在SSL握手之後獲取對等方的證書,以便跟蹤證書的未來更改。如何在成功握手後獲得對等方的QSslCertificate

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,上面的代碼應該可以訪問服務器的證書:

當SSL/TLS會話已經成功地完成了初始握手這個信號被髮射。此時,沒有用戶數據傳輸。該信號可用於對證書鏈執行額外的檢查,例如在網站證書更改時通知用戶。如果回覆不符合預期標準,則應通過連接到此信號的插槽調用QNetworkReply :: abort()來中止。正在使用的SSL配置可以使用QNetworkReply :: sslConfiguration()方法進行檢查。

此外,從documentation of QSslConfiguration::peerCertificate()

因爲對等方證書握手階段中的設置,它是安全的從連接到QSslSocket槽:: sslErrors訪問對方的證書()信號,QNetworkReply :: sslErrors()信號或QSslSocket :: encrypted()信號。

但是,證書總是空的。上面的代碼(輸入應用程序的事件循環後)的調試輸出是:

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的信號進行了測試;結果是一樣的。


MCVE可以在https://bitbucket.org/leemes/ssltest發現,隨意克隆和小提琴:

git clone https://bitbucket.org/leemes/ssltest.git 

我使用Qt 5.4.0和使用Qt 5.3.1測試;結果是一樣的。

回答

相關問題