<p>不能直接用 char* 当加密 Buffer,因为字符串字面量存于只读段,原地加密会触发段错误,且未预留补位空间、strlen 无法反映真实缓冲区长度;std::vector 是最安全选择,自动管理内存、支持任意长度、兼容 C API。</p>

为什么不能直接用 char* 当加密 Buffer 用
很多初学者一上来就写 char* buf = "hello"; 然后传给 AES 加密函数,结果解密乱码或崩溃。根本原因是:字符串字面量存于只读段,encrypt() 内部若尝试原地覆写(比如 OpenSSL 的 EVP_EncryptUpdate()),会触发 Segmentation fault。更隐蔽的问题是:没预留足够空间——加密后数据长度常比原文长(比如 AES-CBC 模式需补位、加 IV),而 strlen() 只算到 \0,根本不管后续内存是否可写。
std::vector<uint8_t></uint8_t> 是最安全的 Buffer 容器
它自动管理堆内存、支持任意长度、无空字符截断风险,且与 C 风格 API 兼容性好。关键操作如下:
- 分配带 padding 的空间:
std::vector<uint8_t> out_buf(in_size + 16);</uint8_t>(AES 块大小为 16 字节) - 传指针给 C 函数:
EVP_EncryptUpdate(ctx, out_buf.data(), &out_len, in_buf.data(), in_size); - 解密后记得用
out_buf.resize(actual_out_len)截掉补位字节,否则后续处理会多出垃圾数据
别用 std::string 存二进制数据——它内部仍以 \0 为潜在终止符,.c_str() 不保证返回完整缓冲区;也别用 new uint8_t[] 手动管理,容易忘 delete[] 或异常泄漏。
指针偏移要小心对齐和越界
处理分块加解密(如大文件流式处理)时,常需指针偏移,但以下错误高频发生:
立即学习“C++免费学习笔记(深入)”;
-
uint8_t* p = buf.data(); p += offset;—— 若offset超过buf.size(),不报错但行为未定义 - IV 必须严格 16 字节对齐,若从 buffer 中取
uint8_t iv[16]; memcpy(iv, p, 16);,得先确认p + 16 - OpenSSL 的
EVP_CIPHER_CTX要求 IV 指针地址能被 4 整除(某些平台),用std::vector通常满足,但手动malloc后ptr + 1可能破坏对齐
解密后如何安全转回字符串或写文件
解密输出是纯二进制,不能直接当 C 字符串用。常见误操作:std::string s(decrypted_buf.begin(), decrypted_buf.end()); 看似正常,但如果解密内容含 \0(比如解密的是图片或 protobuf),std::string 构造没问题,但后续传给 printf("%s", s.c_str()) 就会提前截断。
- 写文件:直接用
std::ofstream::write((const char*)buf.data(), buf.size()),强制按字节写 - 转 C 字符串仅当确定无
\0:用std::string_view(buf.data(), buf.size())避免拷贝,且明确长度语义 - 调试打印二进制:循环用
printf("%02x ", buf[i]),别用%s
真正麻烦的从来不是加解密算法本身,而是 buffer 生命周期、所有权边界和字节解释方式——这些地方出错,错误信息往往不指向 buffer,而是若干步之后的段错误或数据损坏。


















