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 对称加密
使用单个密钥加密数据时,我们采用 CBC 模式下的 AES。重要提示:密钥和 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 Crypto++ 中的 SHA-256 哈希
#include <cryptopp/sha.h>#include <cryptopp/hex.h>#include <iostream>
std::string sha256_cryptopp(const std::string& msg) { CryptoPP::SHA256 hash; byte digest[Cr