Не получается подключиться с SSL-сертификатом к API
Всем привет! Я пытаюсь написать бота биржи ставок Betfair, используя их API, с помощью Qt и C++. Мне нужно подключиться к их API в неинтерактивном режиме, поэтому я создал сертификат и закрытый ключ через OpenSSl (64-bit), которую я скачал отдельно от Qt. На Python у меня все работает хорошо, это означает, что сертификат и ключ созданы правильно.
- import requests
- payload = 'username=myusername&password=mypassword'
- headers = {'X-Application': 'myappkey',
- 'Content-Type': 'application/x-www-form-urlencoded'}
- response = requests.post('https://identitysso-cert.betfair.com/api/certlogin',
- data=payload,
- cert=('C:/Program Files/OpenSSL-Win64/bin/client-2048.crt',
- 'C:/Program Files/OpenSSL-Win64/bin/client-2048.key'),
- headers=headers)
Пытаюсь сделать аналогичное на C++ и Qt, но ничего не выходит.
- #include <QCoreApplication>
- #include <QNetworkAccessManager>
- #include <QFile>
- #include <QNetworkReply>
- #include <QSslKey>
- #include <QSslConfiguration>
- #include <QDebug>
- QSslCertificate sslCertificate()
- {
- QFile certFile("C:/Program Files/OpenSSL-Win64/bin/client-2048.crt");
- if(!certFile.exists()) {
- qDebug()<<"The certificate file doesn't exist";
- return QSslCertificate();
- }
- if(!certFile.open(QIODevice::ReadOnly)) {
- qDebug()<<"Can't open certificate file";
- return QSslCertificate();
- }
- QByteArray certData = certFile.readAll();
- QSslCertificate sslCert(certData);
- if(sslCert.isNull()) {
- qDebug("The certificate has no content");
- return QSslCertificate();
- }
- return sslCert;
- }
- QSslKey sslKey()
- {
- QFile keyFile("C:/Program Files/OpenSSL-Win64/bin/client-2048.key");
- if(!keyFile.exists()) {
- qDebug()<<"The key file doesn't exist";
- return QSslKey();
- }
- if(!keyFile.open(QIODevice::ReadOnly)) {
- qDebug()<<"Can't open key file";
- return QSslKey();
- }
- QByteArray keyData = keyFile.readAll();
- QSslKey sslKey(keyData, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
- if(sslKey.isNull()) {
- qDebug("The key has no content");
- return QSslKey();
- }
- return sslKey;
- }
- int main(int argc, char *argv[])
- {
- QCoreApplication a(argc, argv);
- QNetworkAccessManager manager;
- QNetworkRequest request;
- QByteArray payload("username=myusername&password=mypassword");
- QString url("https://identitysso.betfair.com/api/certlogin");
- QSslConfiguration sslConfig;
- sslConfig.setLocalCertificate(sslCertificate());
- sslConfig.setPrivateKey(sslKey());
- request.setSslConfiguration(sslConfig);
- request.setUrl(url);
- request.setRawHeader("X-Application", "myappkey");
- request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
- qDebug()<<manager.post(request, payload)->readAll();
- return a.exec();
- }
Вывод данной программы следующий:
The certificate has no content
The key has no content
""
qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed
Необходимо заметить, что я полный чайник в этом OpenSSL и слабо понимаю, что здесь происходит. Делал это по гайдам и документации Betfair API.
Много чего гуглил по данной проблеме, поэтому скажу, что возможно, у меня не так:
1. Ничего не прописано в файле .pro по OpenSSL
2. Я использую компилятор MinGW 7.3.0 32-bit, а OpenSSL, с помощью которого у меня сделан сертификат и ключ, 64-bit
3. Не добавлены какие-то либы OpenSSL в какие-то Qt-шные файлы или в файл проекта
Пожалуйста, скажите, как мне сделать так, чтобы все работало прекрасно и легко, как на Python))
Заранее благодарен!
Do you like it? Share on social networks!
- Last comments
- AKApril 1, 2025, 11:41 a.m.Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
- VPMarch 9, 2025, 4:14 p.m.Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…
- ИМNov. 22, 2024, 9:51 p.m.Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
- Now discuss on the forum
- МАApril 1, 2025, 4:21 p.m.0ff763fe-4e50-455d-a3a6-5699c243b1a5_17_44_22_1.xml
- fFeb. 15, 2025, 1:46 p.m.Подскажите, пожалуйста! Как данный класс можно дополнить, чтобы созданные объекты можно было перемещать мышкой по сцене?
- Не запускается компьютер (точнее работает блок , но сам монитор вообще жесть)В общем я ничего с интернета не скачивала в последнее время. На компе никаких левых пр…
- Вопрос решен. Узнать QModelIndex элемента на который мы перетаскиваем другой элемент, можно с помощью функции indexAt(event->position().toPoint()) представления QTreeViev вызываемой в переопр…
TLS initialization failed - говорит что приложению не хватает библиотек OpenSSL, просто скопируйте их и положите рядом с исполняемым файлом
Добавил в папку проекта следующие либы, ничего не изменилось.

Надо что-то где-то дополнительно прописывать или нет? Я просто не очень понимаю...
положи их рядом с исполняемым файлом (.exe) в папке сборки
только смотри разрядность твоей сборки и разрядность библиотек, они должны совпадать, если приложение 64-х битное то и библиотеки должны быть 64-х битными и т.д.
Положил в Build файл, результат не изменился.

Вот да...У меня 32-битный MinGW. Значит, мне надо делать сертификат и ключ через 32-битный OpenSSL, да?
Ну и соответственно либы оттуда брать...
Я скачал Qt-шный 32-битный OpenSSL из Maintenance Tool, сгенерировал новый сертификат и ключ, добавил 32-битные либы в сборку проекта и изменил пути сертификата и ключа на новые. Из вывода вышеуказанной программы ушли строчки:
The certificate has no content
The key has no content
qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed
Но в качестве ответа на запрос приходит по-прежнему почему-то пустая строка. Проверял новые сертификаты на Python, все работает. Может я как-то неправильно запрос отправляю или ответ считываю как-то не так?...
Проблема решилась путем следующих манипуляций:
1. Небольшое изменение url (на https://identitysso-cert.betfair.com/api/certlogin)
2. Установки OpenSSL 32-bit (разрядность должна соответствовать разрядности компилятора)
3. Генерации сертификата и закрытого ключа указанного выше OpenSSL
4. Добавления libcrypto-1_1.dll и libssl-1_1.dll в папку сборки проекта
Всем спасибо!
P.S. Также очень важно работать с ответом запроса только после того, как получен сигнал QNetworkAccessManager::finished, иначе получится чтение ответа до момента его получения от сервера.