Ошибки при использовании OpenSSL для шифрования на C++
Есть код для сервера, который использую шифрование RSA, но не получается его запустить из-за ошибки использование неопределенного типа "rsa_st" в этой строчке std::string serverPublicKey = BN_bn2dec(rsaKeyPair->n); (подчеркивается rsaKeyPair), кто-нибудь знает, как это можно исправить?
#include <iostream>
#include <string>
#include <WinSock2.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "libcrypto.lib")
// Функция создания серверного сокета
SOCKET createServerSocket(int port) {
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
std::cerr << "Ошибка инициализации Winsock." << std::endl;
exit(1);
}
SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, 0);
if (serverSocket == INVALID_SOCKET) {
std::cerr << "Ошибка создания сокета." << std::endl;
WSACleanup();
exit(1);
}
sockaddr_in serverAddress{};
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = INADDR_ANY;
serverAddress.sin_port = htons(port);
if (bind(serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) == SOCKET_ERROR) {
std::cerr << "Ошибка привязки сокета." << std::endl;
closesocket(serverSocket);
WSACleanup();
exit(1);
}
if (listen(serverSocket, 1) == SOCKET_ERROR) {
std::cerr << "Ошибка прослушивания сокета." << std::endl;
closesocket(serverSocket);
WSACleanup();
exit(1);
}
return serverSocket;
}
// Функция принятия соединения
SOCKET acceptConnection(SOCKET serverSocket) {
sockaddr_in clientAddress{};
int clientAddressLength = sizeof(clientAddress);
SOCKET clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddress, &clientAddressLength);
if (clientSocket == INVALID_SOCKET) {
std::cerr << "Ошибка принятия соединения." << std::endl;
closesocket(serverSocket);
WSACleanup();
exit(1);
}
return clientSocket;
}
// Функция отправки данных
void sendData(SOCKET sock, const void* data, size_t dataSize) {
if (send(sock, (const char*)data, dataSize, 0) == SOCKET_ERROR) {
std::cerr << "Ошибка отправки данных." << std::endl;
closesocket(sock);
WSACleanup();
exit(1);
}
}
// Функция получения данных
void receiveData(SOCKET sock, void* buffer, size_t bufferSize) {
int bytesRead = recv(sock, (char*)buffer, bufferSize, 0);
if (bytesRead == SOCKET_ERROR) {
std::cerr << "Ошибка приема данных." << std::endl;
closesocket(sock);
WSACleanup();
exit(1);
}
}
// Функция генерации ключей RSA
void generateRSAKeys(RSA*& rsaKeyPair) {
RSA* rsa = nullptr;
BIGNUM* bne = nullptr;
EVP_PKEY* pkey = nullptr;
bne = BN_new();
if (BN_set_word(bne, RSA_F4) != 1) {
std::cerr << "Ошибка при установке параметров RSA F4." << std::endl;
exit(1);
}
rsa = RSA_new();
if (RSA_generate_key_ex(rsa, 2048, bne, nullptr) != 1) {
std::cerr << "Ошибка генерации ключей RSA." << std::endl;
exit(1);
}
pkey = EVP_PKEY_new();
if (EVP_PKEY_assign_RSA(pkey, rsa) != 1) {
std::cerr << "Ошибка при присвоении ключей RSA EVP_PKEY." << std::endl;
exit(1);
}
rsaKeyPair = EVP_PKEY_get1_RSA(pkey);
if (rsaKeyPair == nullptr) {
std::cerr << "Ошибка при получении ключей RSA." << std::endl;
exit(1);
}
EVP_PKEY_free(pkey);
BN_free(bne);
}
// Функция шифрования RSA
std::string encryptRSA(const std::string& plainText, RSA* rsaKeyPair) {
int rsaKeySize = RSA_size(rsaKeyPair);
std::string encryptedText;
encryptedText.resize(rsaKeySize);
int encryptedLength = RSA_public_encrypt(plainText.size(), (const unsigned char*)plainText.c_str(),
(unsigned char*)encryptedText.data(), rsaKeyPair, RSA_PKCS1_PADDING);
if (encryptedLength == -1) {
std::cerr << "Ошибка при шифровании RSA." << std::endl;
ERR_print_errors_fp(stderr);
exit(1);
}
encryptedText.resize(encryptedLength);
return encryptedText;
}
// Функция дешифрования RSA
std::string decryptRSA(const std::string& encryptedText, RSA* rsaKeyPair) {
int rsaKeySize = RSA_size(rsaKeyPair);
std::string decryptedText;
decryptedText.resize(rsaKeySize);
int decryptedLength = RSA_private_decrypt(encryptedText.size(), (const unsigned char*)encryptedText.c_str(),
(unsigned char*)decryptedText.data(), rsaKeyPair, RSA_PKCS1_PADDING);
if (decryptedLength == -1) {
std::cerr << "Ошибка при дешифровании RSA." << std::endl;
ERR_print_errors_fp(stderr);
exit(1);
}
decryptedText.resize(decryptedLength);
return decryptedText;
}
// Основная функция программы
int main() {
int serverPort = 8888; // Порт сервера
// Создание серверного сокета
SOCKET serverSocket = createServerSocket(serverPort);
std::cout << "Сервер запущен. Ожидание подключения на порту: " << serverPort << "..." << std::endl;
// Принятие соединения
SOCKET clientSocket = acceptConnection(serverSocket);
std::cout << "Подключение принято." << std::endl;
// Генерация ключей RSA
RSA* rsaKeyPair = nullptr;
generateRSAKeys(rsaKeyPair);
// Отправка открытого ключа сервера
std::string serverPublicKey = BN_bn2dec(rsaKeyPair->n);
sendData(clientSocket, serverPublicKey.c_str(), serverPublicKey.size());
std::cout << "Отправлен открытый ключ сервера." << std::endl;
// Получение открытого ключа клиента
char clientPublicKeyBuffer[1024];
receiveData(clientSocket, clientPublicKeyBuffer, sizeof(clientPublicKeyBuffer));
std::string clientPublicKeyString(clientPublicKeyBuffer);
BIGNUM* clientPublicKeyBN = BN_new();
BN_dec2bn(&clientPublicKeyBN, clientPublicKeyString.c_str());
// Шифрование сообщения от клиента с помощью открытого ключа
std::string plainText = "Hello, client!";
std::string encryptedMessage = encryptRSA(plainText, rsaKeyPair);
// Отправка зашифрованного сообщения клиенту
sendData(clientSocket, encryptedMessage.c_str(), encryptedMessage.size());
std::cout << "Отправлено зашифрованное сообщение." << std::endl;
// Закрытие сокетов и очистка
closesocket(clientSocket);
closesocket(serverSocket);
WSACleanup();
RSA_free(rsaKeyPair);
BN_free(clientPublicKeyBN);
std::cout << "Работа сервера завершена. Закрытие программы." << std::endl;
return 0;
}