24 个稳定版本 (3 个主要版本)
3.5.2 | 2024年1月5日 |
---|---|
3.5.1 | 2023年12月15日 |
3.4.0 | 2023年10月9日 |
2.2.1 | 2023年8月9日 |
0.2.0-alpha1 | 2023年5月19日 |
#278 in 加密学
每月548次下载
58KB
1K SLoC
MEMSECURITY
在内存中安全地存储秘密,并通过微架构、物理布局攻击和冷启动攻击防止跨保护边界读取。同时使用 mlock
防止操作系统将这些秘密交换到 RAM,从而在一定程度上防止冷启动攻击。
此算法由 OpenSSH 发明。这种加密方式通过在内存中加密不使用时的敏感数据(如密钥),并在需要时解密,来保护敏感数据。这种方法可以防止各种类型的攻击,包括通过微架构漏洞(如 Spectre 或 Meltdown)进行的跨保护边界读取、物理布局攻击(如 Rowbleed)和冷启动攻击。关键洞察是这些攻击是不完美的,意味着恢复的数据包含位翻转,或者攻击只提供任何给定位的概率。当应用于加密密钥时,这些类型的攻击就足以恢复实际密钥。
然而,此实现使用密钥派生函数从一个称为“预密钥”的大内存区域派生密封密钥。预密钥读取中的任何单个位翻转都会通过密封密钥的所有位级联,使其无法使用,而没有任何错误发生位置的指示。
此 crate 尚未接受审计。使用风险自负!!!
特性
symm_asymm
- 特性启用可用于在丢弃时安全地将内存清零的数据类型。它们实现了来自zeroize
crate 的Zeroize
特性。clonable_mem
- 允许使用symm_asymm
特性启用的数据类型进行克隆。encryption
- 此特性启用使用mlock
和munlock
加密的加密内存,并使用 Ascon128a 密文。random
- 这启用基于rand_core
和rand_chacha
的加密安全随机数生成器。
用法示例
-
生成随机字节
使用随机字节生成器(它基于您使用的操作系统提供的随机性进行加密安全)。必须启用random
功能。use memsecurity::CsprngArray; // Generate a 32 byte array of random bytes let random_bytes = CsprngArray::<32>::gen(); // Assert that the random bytes are not zeroes assert_ne!(random_bytes.expose_borrowed(), &[0u8; 32]); // Use a simplified version of the random bytes generator. use memsecurity::CsprngArraySimple; // Generate one random byte let random8_byte = CsprngArraySimple::gen_u8_byte(); // Generate 8 random bytes let random8 = CsprngArraySimple::gen_u8_array(); assert_eq!(random8.expose_borrowed().len(), 8); // Generate 16 random bytes let random16 = CsprngArraySimple::gen_u16_array(); assert_eq!(random16.expose_borrowed().len(), 16); // Generate 24 random bytes let random24 = CsprngArraySimple::gen_u24_array(); assert_eq!(random24.expose_borrowed().len(), 24); // Generate 32 random bytes let random32 = CsprngArraySimple::gen_u32_array(); assert_eq!(random32.expose_borrowed().len(), 32); // Generate 64 random bytes let random64 = CsprngArraySimple::gen_u64_array(); assert_eq!(random64.expose_borrowed().len(), 64);
-
使用丢弃时为零的数据类型
有时在数据类型被丢弃时需要将其清零。这可以通过确保在不再需要时不在内存中保留加密密钥或密码等秘密来实现。必须启用symm_asymm
功能。如果需要克隆这些秘密,则可以启用clonable_mem
功能(请谨慎使用)。大多数这些都有.expose_borrowed()
方法,如果您想使用该值,则会暴露内部值。use memsecurity::{ZeroizeArray, ZeroizeBytes}; // Create an array of 4 bytes that will be zeroed out when dropped. let array_like = ZeroizeArray::<4>::new([4u8, 3,2,1]); // Use the value array_like.expose_borrowed(); // Create a Vec like array using `BytesMut` from `bytes` crate that re-allocates when it's capacity is exceeded. let mut vector_like = ZeroizeBytes::new(); // Insert a slice of bytes vector_like.set(&[4u8, 5,6,7]); // Must be a byte (u8) type // Use the value vector_like.expose_borrowed();
-
使用 Ascon128a 加密在内存中加密秘密
每次您想在内存中加密密码或加密密钥时,请启用encryption
功能以使用EncryptedMem
类型。此数据中实现了mlock
和munlock
。加密密钥在每个应用程序运行时都会重新生成。use memsecurity::{EncryptedMem, CsprngArray}; // Initialize the struct with a random nonce (Nonce for Ascon128a) let mut foo = EncryptedMem::new(); // Here a some random bytes are generated to simulate // some secret you want to protect. // Here the value must implement `Zeroize` trait // and `impl From<AsRef<[u8]>>` trait so be accepted // by the `encrypt()` and `decrypt()` methods of `EncryptedMem`. let plaintext_bytes = CsprngArray::<32>::gen(); // Encrypt the secret in memory using the randomly // generated encryption key that is `mlocked` foo.encrypt(&plaintext_bytes).unwrap(); // Decrypt the secret using the `mlocked` key let decrypted = foo.decrypt().unwrap(); assert_eq!( plaintext_bytes.expose_borrowed(), decrypted.expose_borrowed() );
许可
此包受 Apache 许可证许可,所有贡献和重新分配都必须具有相同的许可证。
行为准则
所有对话和贡献都必须遵守 Rust 行为准则 https://rust-lang.net.cn/policies/code-of-conduct
依赖关系
~1.7–4MB
~80K SLoC