Cryptography in C++: From Theory to Practice of Encryption and Hashing
Cryptography is the fundamental foundation of modern application security. In C++, developers have access to powerful libraries that allow implementing both symmetric/asymmetric encryption and cryptographic hashing. In this material, we will cover two key libraries: OpenSSL (the de facto standard) and Crypto++ (pure C++, convenient for integration). You will learn how to encrypt data, verify integrity, and protect passwords.
Basic Cryptographic Concepts
Before moving to code, it is important to understand three basic operations:
- Symmetric encryption (AES, ChaCha20) — one key for encryption and decryption. Fast, suitable for large volumes of data.
- Asymmetric encryption (RSA, ECC) — a pair of keys (public/private). Used for key exchange and digital signatures.
- Hashing (SHA-256, MD5) — irreversible transformation of data into a fixed-length string. Used for integrity verification and password storage.
1. Working with OpenSSL in C++
OpenSSL is a cross-platform C library accessible via linking. Installation: sudo apt install libssl-dev (Linux) or via vcpkg/conan for Windows.
Example: Symmetric AES-256-CBC Encryption
#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)); // Generate random key RAND_bytes(iv, sizeof(iv));
std::string data = "Secret message"; std::string encrypted = aes_encrypt(data, key, iv); std::cout << "Encrypted: " << encrypted.size() << " bytes" << std::endl; return 0;}SHA-256 Hashing via 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++ Library (Pure C++ Implementation)
Crypto++ (cryptopp) is a full-featured C++ library with no external dependencies. Installation: sudo apt install libcrypto++-dev or download from cryptopp.com.
Example: RSA Encryption with Crypto++
#include <iostream>#include <string>#include <cryptopp/rsa.h>#include <cryptopp/osrng.h>#include <cryptopp/base64.h>
int main() { using namespace CryptoPP;
AutoSeededRandomPool rng; Inve