Криптография в C++: шифрование и хеширование — полное руководство
Криптография — это фундаментальная основа безопасности современных приложений. В C++ разработчикам доступны мощные библиотеки, позволяющие реализовать шифрование, дешифрование и хеширование данных. В этой статье мы подробно рассмотрим две популярные библиотеки: OpenSSL и Crypto++, а также разберём ключевые концепции: симметричное шифрование (AES), асимметричное шифрование (RSA) и криптографические хеш-функции (SHA-256).
1. Основные понятия криптографии
Прежде чем перейти к коду, важно понимать базовые термины:
- Симметричное шифрование — один ключ используется и для шифрования, и для дешифрования. Примеры: AES, DES, ChaCha20.
- Асимметричное шифрование — пара ключей: открытый (для шифрования) и закрытый (для дешифрования). Примеры: RSA, ECC.
- Хеш-функции — необратимое преобразование данных в строку фиксированной длины. Примеры: SHA-256, MD5 (устарел), BLAKE2.
- Соль (salt) — случайные данные, добавляемые к паролю перед хешированием для защиты от радужных таблиц.
2. Библиотека OpenSSL в C++
OpenSSL — это кроссплатформенная библиотека с открытым исходным кодом, реализующая протоколы SSL/TLS и широкий набор криптографических алгоритмов. Для работы с ней в C++ необходимо подключить заголовочные файлы и линковаться с библиотеками libssl и libcrypto.
Пример 1: Хеширование SHA-256 с помощью OpenSSL
#include <iostream>
#include <openssl/sha.h>
#include <cstring>
std::string sha256(const std::string& input) {
unsigned char hash[SHA256_DIGEST_LENGTH];
SHA256_CTX sha256;
SHA256_Init(&sha256);
SHA256_Update(&sha256, input.c_str(), input.length());
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::string data = "PythonLib - криптография в C++";
std::cout << "SHA-256: " << sha256(data) << std::endl;
return 0;
}
Этот код демонстрирует базовое использование контекста SHA256. Функция SHA256_Init инициализирует контекст, SHA256_Update добавляет данные (можно вызывать несколько раз для потоковой обработки), а SHA256_Final завершает вычисление и записывает результат.
Пример 2: Симметричное шифрование AES-256-CBC
#include <iostream>
#include <openssl/evp.h>
#include <vector>
#include <cstring>
std::vector<unsigned char> 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::vector<unsigned char> ciphertext(plaintext.size() + EVP_CIPHER_block_size(EVP_aes_256_cbc()));
int len = 0;
int ciphertext_len = 0;
EVP_EncryptUpdate(ctx, ciphertext.data(), &len,
reinterpret_cast<const unsigned char*>(plaintext.c_str()), plaintext.size());
ciphertext_len = len;
EVP_EncryptFinal_ex(ctx, ciphertext.data() + len, &len);
ciphertext_len += len;
ciphertext.resize(ciphertext_len);
EVP_CIPHER_CTX_free(ctx);
return ciphertext;
}
int main() {
// 256-битный ключ (32 байта) и 128-битный IV (16 байт)
unsigned char key[32] = "01234567890123456789012345678901";
unsigned char iv[16] = "0123456789012345";
std::string message = "Секретные данные для PythonLib";
auto encrypted = aes_encrypt(message, key, iv);
std::cout << "Зашифровано байт: " << encrypted.size() << std::endl;
return 0;
}
Здесь используется высокоуровневый API EVP (Envelope), который абстрагирует детали конкретного алгоритма. Важно