Не получается подключиться с 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))
Заранее благодарен!
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.Ол саған ұнайды ма? Әлеуметтік желілерде бөлісіңіз!
Пікірлер
- Akiv Doros
- Қар. 11, 2024, 2:58 Т.Қ.
C++ - Тест 004. Указатели, Массивы и Циклы
- Нәтиже:50ұпай,
- Бағалау ұпайлары-4
- molni99
- Қаз. 26, 2024, 1:37 Т.Ж.
C++ - Тест 004. Указатели, Массивы и Циклы
- Нәтиже:80ұпай,
- Бағалау ұпайлары4
- molni99
- Қаз. 26, 2024, 1:29 Т.Ж.
C++ - Тест 004. Указатели, Массивы и Циклы
- Нәтиже:20ұпай,
- Бағалау ұпайлары-10
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, иначе получится чтение ответа до момента его получения от сервера.