Криптография в C++: от теории к практике шифрования и хеширования
Криптография — фундаментальная основа безопасности современных приложений. В C++ разработчику доступны мощные библиотеки, позволяющие реализовать как симметричное/асимметричное шифрование, так и криптографическое хеширование. В этом материале мы разберем две ключевые библиотеки: OpenSSL (де-факто стандарт) и Crypto++ (чистый C++, удобен для интеграции). Вы узнаете, как зашифровать данные, проверить целостность и защитить пароли.
Основные криптографические концепции
Прежде чем перейти к коду, важно понять три базовые операции:
- Симметричное шифрование (AES, ChaCha20) — один ключ для шифрования и расшифровки. Быстрое, подходит для больших объемов данных.
- Асимметричное шифрование (RSA, ECC) — пара ключей (открытый/закрытый). Используется для обмена ключами и цифровых подписей.
- Хеширование (SHA-256, MD5) — необратимое преобразование данных в строку фиксированной длины. Применяется для проверки целостности и хранения паролей.
1. Работа с OpenSSL в C++
OpenSSL — кроссплатформенная библиотека на C, доступная через линковку. Установка: sudo apt install libssl-dev (Linux) или через vcpkg/conan для Windows.
Пример: симметричное шифрование AES-256-CBC
#include <iostream>
#include <string>
#include <openssl/evp.h>
#include <openssl/rand.h>
std::string aes_encrypt(const std::string& plaintext, const unsigned char* key, const unsigned char* iv) {
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, key, iv);
std::string ciphertext(plaintext.size() + 16, '\0');
int len = 0, ciphertext_len = 0;
EVP_EncryptUpdate(ctx, reinterpret_cast<unsigned char*>(&ciphertext[0]), &len,
reinterpret_cast<const unsigned char*>(plaintext.data()), plaintext.size());
ciphertext_len = len;
EVP_EncryptFinal_ex(ctx, reinterpret_cast<unsigned char*>(&ciphertext[ciphertext_len]), &len);
ciphertext_len += len;
ciphertext.resize(ciphertext_len);
EVP_CIPHER_CTX_free(ctx);
return ciphertext;
}
int main() {
unsigned char key[32], iv[16];
RAND_bytes(key, sizeof(key)); // Генерация случайного ключа
RAND_bytes(iv, sizeof(iv));
std::string data = "Секретное сообщение";
std::string encrypted = aes_encrypt(data, key, iv);
std::cout << "Зашифровано: " << encrypted.size() << " байт" << std::endl;
return 0;
}
Хеширование SHA-256 через OpenSSL
#include <iostream>
#include <openssl/sha.h>
std::string sha256(const std::string& str) {
unsigned char hash[SHA256_DIGEST_LENGTH];
SHA256_CTX sha256;
SHA256_Init(&sha256);
SHA256_Update(&sha256, str.c_str(), str.size());
SHA256_Final(hash, &sha256);
std::string output;
for(int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
char buf[3];
sprintf(buf, "%02x", hash[i]);
output += buf;
}
return output;
}
int main() {
std::cout << "SHA-256: " << sha256("Hello, Crypto!") << std::endl;
return 0;
}
2. Библиотека Crypto++ (C++ чистая реализация)
Crypto++ (cryptopp) — полноценная библиотека на C++ без внешних зависимостей. Установка: sudo apt install libcrypto++-dev или скачать с cryptopp.com.
Пример: RSA-шифрование с Crypto++
#include <iostream>
#include <string>
#include <cryptopp/rsa.h>
#include <cryptopp/osrng.h>
#include <cryptopp/base64.h>
int main() {
using namespace CryptoPP;
AutoSeededRandomPool rng;
InvertibleRSAFunction params;
params.GenerateRandomWithKeySize(rng, 2048);
RSA::PrivateKey privateKey(params);
RSA::PublicKey publicKey(params);
std::string plain = "Кри