加密二进制文件必须用binary模式读取并分块处理,优先使用openssl的evp接口自动管理填充、iv和边界;cbc需pkcs#7填充且iv随机唯一,gcm更安全并提供认证标签;切忌密钥复用,须hkdf派生加密与hmac密钥。

加密前必须处理的文件读取模式问题
二进制文件不能用 std::getline 或带 \n 判定的循环读取,否则会截断或错位。必须用 std::ifstream 以 std::ios::binary 模式打开,并配合 read() 按固定字节数拉取数据块。
- 错误示例:
while (file >> buffer)—— 会按空白符分割,彻底破坏二进制结构 - 正确姿势:用
file.read(reinterpret_cast<char>(buf), block_size)</char>,再通过file.gcount()获取实际读入字节数(最后一块常不足) - 注意:
read()不会自动补零,末块长度可能小于预期,加密函数必须支持非整块输入(如 AES-CBC 需填充,AES-GCM 需适配 AAD/nonce)
选择加密算法时的块对齐陷阱
AES 是最常用选择,但不同工作模式对“块”定义不同:ECB/CBC 要求输入长度是 16 字节整数倍;而 CTR、GCM 实际上是流式加密,不强制整块,但 nonce 和 counter 管理仍需按块协调。
- CBC 模式下,末块必须填充(如 PKCS#7),且填充逻辑要与解密端严格一致;若直接丢弃不满块,解密后数据会损坏
- CTR 模式可直接加密任意长度,但每块需独立 nonce 或计数器偏移,
nonce重复会导致密钥流复用,严重泄露明文 - 推荐优先用
OpenSSL的EVP_EncryptUpdate(),它内部处理缓冲和边界,比手写分块更安全
用 OpenSSL 实现安全的分块加密流程
绕过手动管理 padding、IV、counter 的复杂性,直接使用 EVP 接口是最稳妥的做法。核心是把文件流拆成 read() + EVP_EncryptUpdate() 循环,最后调用 EVP_EncryptFinal_ex() 处理末块填充。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, key, iv);
int out_len;
uint8_t out_buf[4096 + EVP_MAX_BLOCK_LENGTH];
while (file.gcount() > 0) {
int in_len = file.gcount();
EVP_EncryptUpdate(ctx, out_buf, &out_len, in_buf, in_len);
output.write(reinterpret_cast<char>(out_buf), out_len);
file.read(reinterpret_cast<char>(in_buf), block_size); // 下一块
}
EVP_EncryptFinal_ex(ctx, out_buf, &out_len); // 写入 padding 后的末块
output.write(reinterpret_cast<char>(out_buf), out_len);
</char></char></char>
-
block_size建议设为 4096 或 65536,太小增加 syscall 开销,太大易占内存 -
iv必须随机生成且随密文一起保存(通常前置 16 字节),不可复用 - 别忘了
EVP_CIPHER_CTX_free(ctx),否则内存泄漏
解密端如何验证块完整性
仅加密不校验等于裸奔。CBC 模式无法检测篡改,建议改用 GCM 模式,或额外计算并存储 HMAC-SHA256。
- GCM 模式下,每块加密后调用
EVP_EncryptFinal_ex()会输出 tag(通常 16 字节),需和密文一起持久化 - 若坚持用 CBC,应在加密完成后,对原始文件计算
HMAC-SHA256(key_hmac, plaintext),并将结果追加到密文末尾;解密时先验签再解密 - 切勿用同一密钥既加密又 HMAC——必须派生两个密钥,例如用
HKDF-SHA256从主密钥分出enc_key和hmac_key
加密不是把数据喂给函数就完事。真正难的是 IV 管理、末块填充一致性、认证标签绑定、密钥隔离——这些地方错一点,整个加密就形同虚设。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










