在Chrome中查看证书详细信息时,Windows显示的给定证书的公钥与连接到加密信号的插槽中Qt返回的公钥不同。
auto onEncrypt = [](QNetworkReply* rpl) {
auto cert = rpl->sslConfiguration().peerCertificate();
auto publicKey = cert.publicKey();
QString winHexKey = "3082010a0282010100d8..."; // as displayed in cert info of Chrome on Windows for the Public Key
auto windowsKey = QByteArray::fromHex(winHexKey.toUtf8());
if (windowsKey == publicKey.toPem())
std::cout << "PEM key matched\n";
else if (windowsKey == publicKey.toDer())
std::cout << "DER key matched\n";
else if (winHexKey == publicKey.toPem().toHex())
std::cout << "Hex PEM key matched\n";
else if (winHexKey == publicKey.toDer().toHex())
std::cout << "Hex DER key matched\n";
else
std::cout << "No match!\n";
std::cout << publicKey.toPem().toHex().toStdString() << '\n'; // 902 characters worth starting with 2d2d2d2d2d
};
QNetworkAccessManager mgr;
QObject::connect(&mgr, &QNetworkAccessManager::encrypted, onEncrypt);
QNetworkRequest r(QUrl::fromUserInput("https://www.qt.io"));
mgr.get(r);
始终导致无匹配。有趣的是,公钥的Hex输出比Windows显示的大得多。
如何获取服务器提供的证书的公钥,并根据证书中的内容进行验证?
答案 0 :(得分:0)
如何获取服务器提供的证书的公钥
公钥是证书的一部分。证书还将包含哈希值,这些哈希值可对证书内容进行一些基本的完整性检查。要检查服务器是否与证书实际匹配,您必须尝试建立加密通道。服务器以与从客户端观察到的证书一致的方式引导加密通道 - 也就是说,服务器与为其呈现的证书匹配;或者它没有 - 这是引起警报的原因。
根据证书中的内容验证它吗?
X.509证书还包含哈希值,可用于完整性检查。
Chrome显示的内容与您的代码之间的差异在于Chrome解码PEM / DER / BER。 DER / BER添加一些额外的元数据来描述字段类型和长度等内容; PEM是底层X.509证书内容的特定编码。
答案 1 :(得分:0)
如果您想通过对等验证发送请求,则无需手动验证。使用QSslConfiguration
并将Chrome中的证书文件设置为CA证书。例如:
QSslConfiguration config = QSslConfiguration::defaultConfiguration();
// Load certificate from file to QByteArray chromeCertificateByteArray
QSslCertificate ca = QSslCertificate(chromeCertificateByteArray);
QList <QSslCertificate> caList;
caList.append(ca);
config.setCaCertificates(caList);
QNetworkRequest request(QUrl::fromUserInput("https://www.qt.io"));
request.setSslConfiguration(config);
QNetworkAccessManager networkManager;
QNetworkReply* reply = networkManager.get(request);