Криптография в C++: шифрование и хеши на OpenSSL и Crypto++

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Криптография в C++: шифрование и хеши с OpenSSL и Crypto++

Надёжная защита данных — базовая потребность любого современного приложения. C++ предоставляет разработчикам мощные инструменты для реализации криптографических алгоритмов: от простого хеширования до сложных схем асимметричного шифрования. В этой статье мы разберём две самые популярные библиотеки — OpenSSL и Crypto++ — и покажем, как с их помощью решать типовые задачи: хеширование, симметричное шифрование (AES) и асимметричное шифрование (RSA).

1. OpenSSL: универсальный криптопровайдер

OpenSSL — де-факто стандарт для криптографии на C/C++. Библиотека поддерживает все основные алгоритмы, сертификаты X.509 и протоколы TLS. Для работы потребуется установить пакет libssl-dev (Linux) или скачать бинарные сборки для Windows.

1.1 Хеширование SHA-256

Простейшая задача — вычислить хеш строки. Используем низкоуровневый API (EVP).

#include <iostream>
#include <openssl/evp.h>
#include <iomanip>

std::string sha256(const std::string& str) {
    EVP_MD_CTX* ctx = EVP_MD_CTX_new();
    EVP_DigestInit_ex(ctx, EVP_sha256(), nullptr);
    EVP_DigestUpdate(ctx, str.data(), str.size());

    unsigned char hash[EVP_MAX_MD_SIZE];
    unsigned int hash_len;
    EVP_DigestFinal_ex(ctx, hash, &hash_len);
    EVP_MD_CTX_free(ctx);

    std::stringstream ss;
    for (unsigned int i = 0; i < hash_len; ++i)
        ss << std::hex << std::setw(2) << std::setfill('0') 
           << (int)hash[i];
    return ss.str();
}

int main() {
    std::cout << sha256("Hello, Crypto!") << std::endl;
    return 0;
}

1.2 Симметричное шифрование AES-256-CBC

Для шифрования данных одним ключом используем AES в режиме CBC. Важно: ключ и IV (вектор инициализации) должны быть случайными.

#include <openssl/evp.h>
#include <vector>

std::vector<unsigned char> aes_encrypt(
    const std::vector<unsigned char>& plaintext,
    const std::vector<unsigned char>& key,
    const std::vector<unsigned char>& iv) 
{
    EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
    EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, key.data(), iv.data());

    std::vector<unsigned char> ciphertext(plaintext.size() + 16);
    int out_len, tmp_len;
    EVP_EncryptUpdate(ctx, ciphertext.data(), &out_len, plaintext.data(), plaintext.size());
    EVP_EncryptFinal_ex(ctx, ciphertext.data() + out_len, &tmp_len);
    out_len += tmp_len;
    ciphertext.resize(out_len);

    EVP_CIPHER_CTX_free(ctx);
    return ciphertext;
}

Расшифровка выполняется аналогично через EVP_DecryptInit_ex и EVP_DecryptUpdate.

1.3 Асимметричное шифрование RSA

RSA используется для обмена ключами или подписи данных. Генерация пары ключей:

#include <openssl/rsa.h>
#include <openssl/pem.h>

RSA* generate_rsa_keypair(int bits = 2048) {
    RSA* rsa = RSA_new();
    BIGNUM* e = BN_new();
    BN_set_word(e, 65537);
    RSA_generate_key_ex(rsa, bits, e, nullptr);
    BN_free(e);
    return rsa;
}

// Сохранение публичного ключа в PEM
void save_public_key(RSA* rsa, const char* filename) {
    BIO* bio = BIO_new_file(filename, "w");
    PEM_write_bio_RSA_PUBKEY(bio, rsa);
    BIO_free(bio);
}

2. Crypto++: C++-ориентированная альтернатива

Crypto++ (библиотека Wei Dai) предлагает более «родной» для C++ интерфейс: шаблоны, RAII, потоки. Не требует внешних зависимостей.

2.1 Хеширование SHA-256 в Crypto++

#include <cryptopp/sha.h>
#include <cryptopp/hex.h>
#include <iostream>

std::string sha256_cryptopp(const std::string& msg) {
    CryptoPP::SHA256 hash;
    byte digest[CryptoPP                    

Рекомендаций