当前位置: 首页 > news >正文

【C/C++】explicit_bzero

explicit_bzero

explicit_bzero 是一个为了解决 memset 在安全清除内存场景中可能被优化器移除的问题而设计的函数,广泛用于安全编程中,比如密码、密钥清除等。


Introduce

头文件

#include <string.h>

函数原型

void explicit_bzero(void *s, size_t n);

功能说明

将内存区域 s 开始的 n 个字节强制清零(写入 0),确保不会被编译器优化掉


为什么不能用 memset

当你写:

char key[32];
// ... 使用 key ...
memset(key, 0, sizeof(key));

有些编译器会发现 key 后面就不再使用,于是优化器会移除 memset 调用,导致密码/密钥未被真正擦除,造成信息泄露风险。

explicit_bzero 的实现避免了这一问题:

  • 使用 volatile 指针或编译器 barrier;
  • 或直接调用外部函数(编译器无法内联);
  • 保证操作不可优化,满足安全清除需求

可用平台

平台是否支持 explicit_bzero
✅ FreeBSD原生支持
✅ OpenBSD原生支持(首发平台)
✅ glibc >= 2.25(2017)支持
✅ macOS 10.12+可用
🚫 Windows不支持(用 SecureZeroMemory

用法示例

#include <string.h>int main() {char secret[32] = "TopSecretPassword123!";// 使用 secret 做某些操作...// 清除 secret(防止泄露)explicit_bzero(secret, sizeof(secret));return 0;
}

📌 即使 secret 后续没有再用,这个清除也不会被优化掉!


bzero 区别?

函数是否会被优化器移除是否已废弃推荐使用
memset✅ 有风险❌ 不用于清除敏感数据
bzero✅ 有风险✅ 已废弃(非标准)
explicit_bzero❌ 安全✅ ✅ ✅

Windows 等平台

Windows 没有 explicit_bzero,可以用:

#include <windows.h>
SecureZeroMemory(ptr, size);

或者自己写:

void secure_memzero(void* p, size_t len) {volatile unsigned char* vp = (volatile unsigned char*)p;while (len--) {*vp++ = 0;}
}

跨平台、安全、可靠的 explicit_bzero 封装实现

  • Linux(glibc >= 2.25)使用系统 explicit_bzero
  • macOS 使用 explicit_bzerobzero
  • Windows 使用 SecureZeroMemory
  • 其他平台使用手动 volatile 写法

跨平台安全内存清除封装

#pragma once#include <cstddef>  // for size_t#if defined(_WIN32)#include <windows.h>
#elif defined(__has_include)#if __has_include(<string.h>)#include <string.h>#endif
#endifnamespace secure {// 可移植 secure_memzero 封装
inline void memzero(void* ptr, size_t len) {if (!ptr || len == 0) return;#if defined(_WIN32)// Windows 安全 APISecureZeroMemory(ptr, len);#elif defined(__GLIBC__) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))// glibc 2.25+ 提供 explicit_bzeroexplicit_bzero(ptr, len);#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__)// macOS / BSD 系统一般也有 explicit_bzeroexplicit_bzero(ptr, len);#else// 手动 volatile 写法,防止优化器移除volatile unsigned char* p = reinterpret_cast<volatile unsigned char*>(ptr);while (len--) {*p++ = 0;}
#endif
}} // namespace secure

使用方式

#include "secure_memzero.hpp"int main() {char password[32] = "MySecretPassword";// ... 使用 password ...// 安全清除secure::memzero(password, sizeof(password));return 0;
}

测试建议

  1. Release 模式下测试,确保 secure::memzero 不被优化掉。
  2. 检查编译器汇编输出(例如 objdump -d)确保有写入指令。
  3. 如在密码模块中使用,建议配合内存保护机制(如 mlock)以防 swap 泄露。

优点

特性描述
安全防止编译器优化清零操作
跨平台兼容 Linux/macOS/Windows/FreeBSD 等系统
无依赖不依赖 C11 memset_s
可内联单头文件,适用于库内/项目中任意使用

总结

特性说明
安全不会被编译器优化
用途清除密码、私钥等敏感数据
可移植性glibc 2.25+、BSD、macOS 支持,Windows 需替代方案
推荐场景密码学、加密库、认证信息清除等
http://www.dtcms.com/a/299654.html

相关文章:

  • windows安装mysql8缺少时区信息
  • C语言开发工具Win-TC
  • Flask input 和datalist结合
  • C语言数据结构笔记6:函数指针的使用
  • 5. 流程控制语句
  • 哈希指针与数据结构:构建可信数字世界的基石
  • 记一次腾讯云临时密钥接管存储桶
  • obd运维OceanBase数据库的常见场景
  • C++11特性详解(上)
  • 解决使用vscode连接服务器出现“正在下载 VS Code 服务器...”
  • 实现网页访问/接口调用KernelMemory
  • cacti的命令执行和回显
  • 八股文整理——计算机网络
  • 【数据结构】队列和栈练习
  • HTTPS的基本理解以及加密流程
  • Nestjs框架: 基于Mongodb的多租户功能集成和优化
  • 顶顶通呼叫中心系统之创建与注册分机
  • 矩阵乘法计算
  • 安德鲁·卡帕西:深入探索像ChatGPT这样的大语言模型
  • 免费 PDF 转 Word 工具:无水印 / 支持批量转换,本地运行更安全【附工具下载】
  • Ubuntu系统 系统盘和数据盘扩容具体操作
  • 【第二章-数据的表示和运算】
  • vulhub Web Machine(N7)靶场攻略
  • 详解力扣高频SQL50题之1193. 每月交易 I【简单】
  • 数据恢复与备份
  • RS485转Profinet网关配置指南:高效启动JRT激光测距传感器测量模式
  • SpringMVC相关基础知识
  • HTML5 Canvas 绘制圆弧效果
  • Centos安装HAProxy搭建Mysql高可用集群负载均衡
  • 力扣112. 路径总和