我正在使用 QWebView 在 Qt 中开发我的自定义浏览器,并且我正在尝试制作我自己的可信证书的根证书存储,这些证书是从 mozilla 项目中获取的。
我使用 QSslSocket::setDefaultCaCertificates() 来覆盖默认证书。但是我无法加载 https://www.gmail.com,就像在 mozilla 中一样。
我已将 gmail 所需的所有根证书设置到我的商店。
谁能指导我?
我正在使用 QWebView 在 Qt 中开发我的自定义浏览器,并且我正在尝试制作我自己的可信证书的根证书存储,这些证书是从 mozilla 项目中获取的。
我使用 QSslSocket::setDefaultCaCertificates() 来覆盖默认证书。但是我无法加载 https://www.gmail.com,就像在 mozilla 中一样。
我已将 gmail 所需的所有根证书设置到我的商店。
谁能指导我?
您无法连接的原因是因为2F:DF:BC:F6:AE:91:52:6D:0F:9A:A3:DF:40:34:3E:9A
当您连接到 www.gmail.com 时向您提供的 SSL 证书(带有 serial )是为不同的域 - www.google.com 颁发的。这与根 CA 证书存储无关,因为无需根 CA 证书即可将证书的主题 CN 字段与您尝试连接的主机进行比较。您可以通过调用忽略此错误和其他 SSL 错误。
为了避免此错误,您可以直接连接到https://mail.google.com ,这是您尝试连接到https://www.gmail时被重定向到的域.com
void QNetworkReply::ignoreSslErrors () [virtual slot]
下面是一个工作示例,它将向您显示确切的 SSL 错误和 QNAM 级别错误。线路 B1 或线路 B2 必须同时处于活动状态。如果您想查看默认(系统)根 CA 证书存储会发生什么,您可以评论 A 行。此代码使用了两个证书;CA 的序列号证书30:00:00:02
应该放在一个名为的文件中ThawteSGCCA.crt
,而 CA 的序列号证书70:BA:E4:1D:10:D9:29:34:B6:38:CA:7B:03:CC:BA:BF
应该放在一个名为BuiltinObjectToken-VerisignClass3PublicPrimaryCertificationAuthority.crt
.
#include <QtGui/QApplication>
#include <QtCore/QDebug>
#include <QtCore/QList>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QSslConfiguration>
#include <QtNetwork/QSslSocket>
#include <QtNetwork/QSslError>
#include <QtWebKit/QWebFrame>
#include <QtWebKit/QWebPage>
class Handler : public QObject{
Q_OBJECT
public slots:
void slotLoadFinished(bool ok) {
if (ok) {
qDebug() << "Page size: " << static_cast<QWebPage*>(sender())->mainFrame()->toHtml().size();
}
}
void slotFinished(QNetworkReply * reply) {
if (reply->error() == QNetworkReply::NoError) {
qDebug() << "connected to " << reply->url();
qDebug() << "HTTP status: " << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
} else {
qDebug() << "error while connecting to " << reply->url();
qDebug() << "error code: " << reply->error();
qDebug() << "error string: " << reply->errorString();
}
}
void slotSslErrors(QNetworkReply * reply, QList<QSslError> const & errors) {
qDebug() << "SSL errors: " << errors;
qDebug() << "peer's certificate: "
<< reply->sslConfiguration().peerCertificate();
}
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Handler handler;
// CA certs for:
// 1. cert with Subject.CN == mail.google.com cert with serial 1f:19:f6:de:35:dd:63:a1:42:91:8a:d5:2c:c0:ab:12
// 2. cert with Subject.CN == www.google.com cert with serial 2F:DF:BC:F6:AE:91:52:6D:0F:9A:A3:DF:40:34:3E:9A
QList<QSslCertificate> CAcerts =
// serial 30:00:00:02
QSslCertificate::fromPath("ThawteSGCCA.crt") +
// serial 70:BA:E4:1D:10:D9:29:34:B6:38:CA:7B:03:CC:BA:BF
QSslCertificate::fromPath("BuiltinObjectToken-VerisignClass3PublicPrimaryCertificationAuthority.crt");
qDebug() << "root CA certificates:\n"
<< CAcerts
<< "\n";
QSslSocket::setDefaultCaCertificates(CAcerts); // line A
QWebPage page;
// OK because cert with serial 1f:19:f6:de:35:dd:63:a1:42:91:8a:d5:2c:c0:ab:12 is for host mail.google.com
// page.mainFrame()->load(QUrl("https://mail.google.com")); // line B1
// SSL ERROR "The host name did not match any of the valid hosts for this certificate"
// because cert with serial 1f:19:f6:de:35:dd:63:a1:42:91:8a:d5:2c:c0:ab:12 is NOT for www.gmail.com
page.mainFrame()->load(QUrl("https://www.gmail.com")); // line B2
QObject::connect(page.networkAccessManager(), SIGNAL(finished(QNetworkReply*)), &handler, SLOT(slotFinished(QNetworkReply*)));
QObject::connect(page.networkAccessManager(), SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)), &handler, SLOT(slotSslErrors(QNetworkReply*,QList<QSslError>)));
QObject::connect(&page, SIGNAL(loadFinished(bool)), &handler, SLOT(slotLoadFinished(bool)));
return app.exec();
}
#include "main.moc"