c++标准库不支持文件加密,必须依赖openssl等第三方库;推荐aes-256-cbc配合随机iv和pkcs7填充,密钥须安全管理,文件须二进制模式读写。

加密前先确认:C++ 标准库不提供文件加密
别浪费时间翻 std::fstream 或 <filesystem></filesystem> 的文档了——C++20 之前标准库根本没有加密能力。所有“用 C++ 加密文件”的实现,本质都是调用第三方密码学库处理字节流,再写回磁盘。你真正要选的是底层算法和封装方式,不是“怎么用 C++ 写”,而是“用哪个库 + 怎么安全地喂数据”。
推荐方案:OpenSSL + AES-256-CBC(最常见且可验证)
OpenSSL 是目前最广泛审计、跨平台、有完整 AEAD 支持(如 GCM)的选项。直接用 EVP_EncryptInit_ex 系列 API 比手撸 DES/EVP 封装更可靠,也比轻量库(如 libsodium)在 Windows 上更容易链接。
- 必须用随机
IV(16 字节),且每次加密都重生成,不能硬编码或复用 - 密钥不能明文写在代码里;建议从环境变量或密钥管理服务(如 HashiCorp Vault)读取,至少用
std::string临时持有后立即memset清零 - 加密后务必把
IV和密文一起写入文件(例如 IV 在前 16 字节),否则解密时无法还原 - 不要自己拼接 padding:用
PKCS7填充(OpenSSL 默认),别手动补\0
示例关键步骤:
unsigned char iv[AES_BLOCK_SIZE]; RAND_bytes(iv, AES_BLOCK_SIZE); // 必须调用 EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, key, iv); // ... 处理输入缓冲区 // 最后 write(iv, 16) + write(ciphertext, len)
常见错误:用 XOR 当加密,或误用 std::random_device
有人用 std::xor_combine 或简单循环异或密钥字节,这根本不是加密,只是编码,几秒就被 xxd + 频率分析破解。还有人以为 std::random_device 能当密码学安全随机源——在 Windows MSVC 下它常退化为 rand(),输出可预测,RAND_bytes 或 /dev/urandom 才是正解。
立即学习“C++免费学习笔记(深入)”;
- XOR 不是加密算法,没有混淆扩散,不抗已知明文攻击
-
std::random_device::entropy()返回 0?说明不可靠,立刻换 OpenSSL 的RAND_bytes - 用
std::mt19937加密?同样不行,它是伪随机,种子一旦泄露全盘崩溃
解密失败的典型报错:bad decrypt 或长度异常
绝大多数 bad decrypt 来自 IV 不匹配或密钥错误,但更隐蔽的问题是:读文件时没按二进制模式打开,导致 Windows 下遇到 \r\n 自动转义,密文被篡改;或者没正确处理最后一块的 padding 去除逻辑。
- 务必用
std::ios::binary打开文件,std::ifstream f("x.enc", std::ios::binary) - 解密后调用
PKCS7_unpad(或手动检查末字节值),别直接截断 - 如果加密用的是 GCM 模式,记得校验
tag字段(通常 16 字节),不校验等于没加密
一个容易被忽略的点:OpenSSL 1.1.1+ 默认启用 FIPS 模式时,某些算法会被禁用,EVP_get_cipherbyname("aes-256-cbc") 可能返回 nullptr,得查 ERR_print_errors_fp 看具体提示。











