当前位置: 首页 > 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.xdnf.cn/news/1194679.html

相关文章:

  • C++核心编程学习--对象特性--友元
  • [C/C++内存安全]_[中级]_[再次探讨避免悬垂指针的方法和检测空指针的方法]
  • OpenCV学习探秘之一 :了解opencv技术及架构解析、数据结构与内存管理​等基础
  • React入门学习——指北指南(第三节)
  • 云计算技术之docker build构建错误
  • Swagger 配置及使用指南
  • sklearn库中有关于数据集的介绍
  • 命令行创建 UV 环境及本地化实战演示—— 基于《Python 多版本与开发环境治理架构设计》的最佳实践
  • 【计算机组成原理】第一章:计算机系统概述
  • Django+celery异步:拿来即用,可移植性高
  • 【408二轮强化】数据结构——线性表
  • C++ TAP(基于任务的异步编程模式)
  • 在VS Code中运行Python:基于Anaconda环境或Python官方环境
  • 如何在 Ubuntu 24.04 或 22.04 中创建自定义 Bash 命令
  • 机器学习——随机森林算法分类问题案例解析(sklearn)
  • Nacos-服务注册,服务发现(二)
  • 智慧城市多目标追踪精度↑32%:陌讯动态融合算法实战解析
  • bmp280的压力数据采集(i2c设备驱动+设备树编写)
  • 数据结构 二叉树(3)---层序遍历二叉树
  • 知识图谱的初步探索
  • 智慧农业病虫害识别准确率↑32%:陌讯多模态融合算法实战解析
  • 特产|基于SSM+vue的南阳特产销售平台(源码+数据库+文档)
  • LLM中 词嵌入向量中的正负值表示什么含义
  • GO 从入门到精通
  • python---元组解包(Tuple Unpacking)
  • VisionPro系列讲解 - 03 Simulator 模拟器使用
  • 【RHCSA 问答题】第 13 章 访问 Linux 文件系统
  • Windows Server存储池,虚拟磁盘在系统启动后不自动连接需要手动连接
  • 【js】Function.prototype.apply与Function.prototype.apply.call
  • 学习日志19 python