1 个不稳定版本

0.1.0 2019 年 11 月 9 日

#1904加密学

MIT 许可证

14KB
137

SafeBox - 减少内存中的秘密泄露

Documentation

通过内联函数和在不安全代码块中进行保护,SafeBox 帮助您降低在内存中泄露某些秘密的机会。

  • 所有读取和写入访问必须通过 get_refget_mut 方法进行。这两种方法都被标记为 unsafe。目的是防止隐式复制。并希望程序员在看到不安全的情况下更加小心。
  • 在析构时清零内存。
  • API 可以肯定得到改进,欢迎提交 PR 和 Issues 进行讨论。

除非您愿意在互联网上信任一个陌生人,否则请勿在生产环境中使用

示例

use safebox::SafeBox;
use rand::prelude::*;
let a = SafeBox::new_slice_with(8, &random::<u8>);
unsafe {
    println!("My secret: {:?}", secret.get_ref());
}

打印(非确定性的)

My secret: [242, 144, 235, 196, 84, 35, 85, 232]

片段

为了将一块 RAM 清零,需要调用 memset(0) 之外的东西。有一些层级的优化和抽象在对抗我们

  1. 编译器可以完全放弃清零。由于该值从未再次使用,编译器假设没有副作用,并会愉快地删除该代码以提高速度。
  2. 编译器可以重新排序内存操作。
  3. 同样,硬件也可以重新排序内存操作。
  4. 此外,硬件可能不会立即将缓存刷新到 RAM 中。

考虑到上述因素,我们必须确保内容在 RAM 中不会意外复制

  1. 获取内容的所有权可以将它移动到任何地方,包括栈/堆。在 RAM 中留下内容的一个副本。
  2. 同样,对内容进行 &mut 访问允许内存交换或替换。

最后,操作系统也可能介入

  1. 操作系统可以将 RAM 移动到持久存储的交换区。
  2. 同一内存空间中的任何线程都可以随意读取和写入内存。
  3. 当系统休眠时,操作系统很可能会将 RAM 内容复制到持久存储。

此 crate 使用 volatile write 和 atomic fence 解决了 1) 到 4) 问题。5) 和 6) 被放在不安全函数后面。当然,程序员负责保持不变性;但最终;这需要使用可见的不安全块。

忽略了操作系统方面。7) 和 8) 可以通过 mlock 和 mprotect 系统调用解决。至于 9),您应该使用加密存储。

无运行时依赖