在 ssl单向证书和双向证书校验测试及搭建流程 文章中,已经做了基于https的单向认证和双向认证,,,
在进行双向认证时,采用的是curl工具或浏览器充当客户端去验证。
此次采用QT提供的接口去开发客户端向服务器发送请求,来验证https的双向认证流程。
1、准备
依然以 ssl单向证书和双向证书校验测试及搭建流程 该文章作为前提条件进行开发。
开发环境:
客户端:Win10-64 + Qt5.13-MingW.32
服务端:Linux + openssl-1.1.1.f + nginx/1.18.0
2、分析
实际上在上文所指向的文章中,我们通过curl命令行来作为客户端向服务器发起了基于https的双向认证。见下图。
在这里指定了客户端私钥和客户端的证书。。。
再次回顾用浏览器充当客户端去进行https的双向认证,在那里我们事先导入了客户端的p12证书,p12证书实际上是客户端crt证书和客户端私钥key的结合体。
综上所述,两种方法中有一个共性,就是发送时都需要客户端的证书和私钥。。
双向校验时,肯定是要携带客户端的证书给服务器的。。。。
那么自然的,在QT中也要按照此套路开发(发送请求时携带证书与私钥),,,QT也提供了相应的接口。
2、核心代码
void MainWindow::testSsl()
{
// 加载客户端证书
QFile crtFile("C:\\Users\\XingWei\\Documents\\untitled42\\client.crt");
crtFile.open(QIODevice::ReadOnly);
QSslCertificate certificate(&crtFile, QSsl::Pem);
crtFile.close();
// 加载客户端私钥
QByteArray passPhrase("123456"); // 私钥的密码
QFile keyFile("C:\\Users\\XingWei\\Documents\\untitled42\\client.key");
keyFile.open(QIODevice::ReadOnly);
QSslKey privateKey(&keyFile, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, passPhrase);
keyFile.close();
// ssl配置
QSslConfiguration conf;
conf.setPeerVerifyMode(QSslSocket::QueryPeer);
conf.setProtocol(QSsl::TlsV1SslV3);
conf.setPrivateKey(privateKey);
conf.setLocalCertificate(certificate);
QNetworkRequest request;
request.setUrl(QUrl("https://50.50.1.118"));
request.setSslConfiguration(conf);
QEventLoop loop;
QNetworkReply* reply = m_manager.get(request);
connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
connect(reply, &QNetworkReply::finished, this, [=] {
qDebug() << "####################### get data finished...";
QByteArray data = reply->readAll();
qDebug() << data;
});
loop.exec();
qDebug() << "#############> " << reply->errorString() << reply->error();
}
3、运行及抓包分析
通过抓包,可以明显的看出,客户端和服务器各自向彼此发送了各自的证书。。
同时,服务器也正常响应客户端了。。