1 个不稳定版本
0.1.0 | 2019 年 11 月 9 日 |
---|
#1904 在 加密学
14KB
137 行
SafeBox - 减少内存中的秘密泄露
通过内联函数和在不安全代码块中进行保护,SafeBox 帮助您降低在内存中泄露某些秘密的机会。
- 所有读取和写入访问必须通过
get_ref
和get_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) 之外的东西。有一些层级的优化和抽象在对抗我们
- 编译器可以完全放弃清零。由于该值从未再次使用,编译器假设没有副作用,并会愉快地删除该代码以提高速度。
- 编译器可以重新排序内存操作。
- 同样,硬件也可以重新排序内存操作。
- 此外,硬件可能不会立即将缓存刷新到 RAM 中。
考虑到上述因素,我们必须确保内容在 RAM 中不会意外复制
- 获取内容的所有权可以将它移动到任何地方,包括栈/堆。在 RAM 中留下内容的一个副本。
- 同样,对内容进行 &mut 访问允许内存交换或替换。
最后,操作系统也可能介入
- 操作系统可以将 RAM 移动到持久存储的交换区。
- 同一内存空间中的任何线程都可以随意读取和写入内存。
- 当系统休眠时,操作系统很可能会将 RAM 内容复制到持久存储。
此 crate 使用 volatile write 和 atomic fence 解决了 1) 到 4) 问题。5) 和 6) 被放在不安全函数后面。当然,程序员负责保持不变性;但最终;这需要使用可见的不安全块。
忽略了操作系统方面。7) 和 8) 可以通过 mlock 和 mprotect 系统调用解决。至于 9),您应该使用加密存储。