QSslCertificate, как получить открытый ключ, как показано в Windows
Открытый ключ данного сертификата, отображаемый Windows при просмотре сведений о сертификате в Chrome, отличается от того, что 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);
Всегда приводит к совпадению. Интересно, что шестнадцатеричный вывод открытого ключа намного больше, чем то, что отображает Windows.
Как можно получить открытый ключ сертификата, представленного сервером, и сравнить его с тем, что присутствует в сертификате?
2 ответа
Как получить открытый ключ сертификата, представленного сервером
Открытый ключ является частью сертификата. Сертификат также будет содержать хэши, которые позволяют выполнять некоторые базовые проверки целостности содержимого сертификата. Чтобы проверить, действительно ли сервер соответствует сертификату, вы должны попытаться установить зашифрованный канал. Либо сервер загружает зашифрованный канал способом, который согласуется с сертификатом, наблюдаемым от клиента, то есть сервер совпадает с сертификатом, представленным для него; или это не так - что является причиной для тревоги.
сверить его с тем, что присутствует в сертификате?
Сертификаты X.509 также содержат хэши, которые можно использовать для проверки целостности.
Расхождение между тем, что показывает Chrome, и тем, что делает ваш код, заключается в том, что Chrome декодирует PEM/DER/BER. DER/BER добавляет некоторые дополнительные метаданные для описания таких вещей, как тип поля и длина; PEM - это конкретная кодировка содержимого основного сертификата X.509.
Если вы хотите отправить запрос с одноранговой проверкой, нет необходимости проверять вручную. использование 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);