Rust安全存储库stronghold-runtime的使用,提供加密数据存储和安全运行时环境的高性能解决方案
Rust安全存储库stronghold-runtime的使用,提供加密数据存储和安全运行时环境的高性能解决方案
Stronghold new runtime
这个crate提供了多种安全存储数据的方式,无论是在RAM、磁盘还是分散到非连续的数据结构中。所有这些内存类型都实现了LockedMemory
特性,使您可以分配或解锁存储的数据。
还提供了一个Buffer
类型,它实现了基本的安全措施,用于临时存储任何计算的数据。
Buffer
包含一些"最小"安全措施的内存,如:
- 保护区域
- 哨兵值
- 恒定时间比较
- 丢弃时清零内存
- 内存页的访问控制
- 防止内存转储的系统标志
受保护内存中的值是明文存储的。这些值可以通过borrow()
或borrow_mut()
获取引用访问。由于值是明文存储的,Buffer
实例应尽可能短命。
Buffer
的主要函数是alloc()
、borrow()
、borrow_mut
。
LockedMemory
锁定内存用于长时间存储敏感数据。
您可以使用alloc()
创建一个LockedMemory
实例,或使用update()
给它一个新值。正如特性名称所示,存储在LockedMemory
中的数据是锁定的,您可以使用unlock()
检索。解锁的数据将返回在一个Buffer
中。
分配LockedMemory
时,您必须选择它将如何存储和如何锁定。有3种类型实现了LockedMemory
:RamMemory
、FileMemory
和NonContiguousMemory
。
RamMemory
数据将存储在RAM内存中,具有与Buffer
类型相同的安全措施。此外,用户可以通过提供加密密钥选择对其数据进行加密。
注意:带有非加密数据的RamMemory
本质上是一个Buffer
类型的包装器。
FileMemory
数据存储在磁盘内存中,可以加密。
保护文件的安全措施:
- 文件的访问控制(操作系统相关)
- 数据与噪声混合
- 文件在丢弃时被清零并删除
注意:通常磁盘内存比RAM内存更脆弱,但我们相信使用不同类型的内存可以提高数据安全性。
NonContiguousMemory
数据使用Boojum方案分成两部分。基本上数据被分成两部分:
- 一个部分是随机数据
- 另一个部分是与第一个部分的哈希值进行异或运算的数据
通过将第二个部分与第一个部分的哈希值进行异或运算来重建数据。
非连续内存通过迫使攻击者恢复多个部分来获取原始数据来提高安全性。用户可以选择在RAM内存中或RAM和磁盘中分散数据(以多样化内存存储)。
此外,可以定期刷新分片。分片的值将分别修改,以便仍然可以重建原始数据。
注意:分片中的数据与哈希摘要进行异或运算,因此存储在非连续内存中的数据只能具有哈希摘要的大小。这看起来可能有限制,但在遵循下一节中描述的使用建议时很适合。
使用建议
我们关于如何使用crate存储敏感数据的建议:
- 数据加密存储在
RamMemory
中 - 加密密钥存储在
NonContiguousMemory
中,分布在RAM和磁盘上
因此,数据安全性取决于加密方案的强度和加密密钥在非连续内存中的"混淆"。
完整示例代码
use stronghold_runtime::{Buffer, RamMemory, NonContiguousMemory, LockedMemory};
fn main() {
// 示例1: 使用Buffer临时存储敏感数据
let mut buffer = Buffer::alloc(32).unwrap();
{
let mut data = buffer.borrow_mut();
data.copy_from_slice(b"this is very sensitive data");
}
// buffer在作用域结束时自动清零
// 示例2: 加密存储在RAM中
let key = b"32-byte-long-encryption-key-here...";
let mut ram_mem = RamMemory::alloc(key, 64).unwrap();
ram_mem.update(b"data to be encrypted in ram").unwrap();
// 解锁RAM内存中的数据
let decrypted = ram_mem.unlock().unwrap();
println!("Decrypted: {:?}", decrypted.borrow());
// 示例3: 使用推荐方案 - 加密数据+分散密钥
let data_key = b"another-32-byte-encryption-key";
let mut secure_data = RamMemory::alloc(data_key, 128).unwrap();
secure_data.update(b"super secret enterprise data").unwrap();
// 将加密密钥存储在非连续内存中
let mut key_storage = NonContiguousMemory::alloc(32).unwrap();
key_storage.update(data_key).unwrap();
// 刷新密钥分片以增强安全性
key_storage.refresh().unwrap();
// 完整使用流程:
// 1. 从非连续内存获取加密密钥
let retrieved_key = key_storage.unlock().unwrap();
let key_ref = retrieved_key.borrow();
// 2. 用密钥解锁加密数据
let mut data_store = RamMemory::alloc(&key_ref, 128).unwrap();
data_store.update(secure_data.unlock().unwrap().borrow()).unwrap();
}
这个示例展示了stronghold-runtime的主要功能:
Buffer
用于短期安全存储RamMemory
提供加密的RAM存储NonContiguousMemory
用于安全存储加密密钥- 推荐的组合使用方案
注意所有敏感数据都会自动清零,并且加密密钥分散存储,提供了深度防御的安全策略。
Rust安全存储库stronghold-runtime使用指南
简介
stronghold-runtime是一个Rust实现的加密数据存储和安全运行时环境的高性能解决方案。它提供了安全的存储机制和运行时保护,适用于需要高安全性保障的应用程序。
主要特性
- 安全的加密数据存储
- 内存保护机制
- 高性能加密操作
- 安全的运行时环境
- 防止内存泄漏和侧信道攻击
安装方法
在Cargo.toml中添加依赖:
[dependencies]
stronghold-runtime = "0.7"
基本使用方法
1. 创建安全存储库
use stronghold_runtime::Stronghold;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 创建新的Stronghold实例
let stronghold = Stronghold::default();
// 或者从文件加载
// let stronghold = Stronghold::load("path/to/store")?;
Ok(())
}
2. 存储和检索加密数据
use stronghold_runtime::{Stronghold, Location};
fn store_and_retrieve() -> Result<(), Box<dyn std::error::Error>> {
let mut stronghold = Stronghold::default();
// 定义存储位置
let location = Location::generic("my_app", "sensitive_data");
// 存储数据
let secret_data = b"my secret data".to_vec();
stronghold.store(location.clone(), secret_data)?;
// 检索数据
if let Some(data) = stronghold.retrieve(&location)? {
println!("Retrieved data: {:?}", data);
}
Ok(())
}
3. 使用安全运行时
use stronghold_runtime::{SecureRuntime, Protected};
fn secure_computation() -> Result<(), Box<dyn std::error::Error>> {
// 创建安全运行时
let runtime = SecureRuntime::new()?;
// 保护敏感数据
let secret = Protected::new(b"secret_value".to_vec());
// 在安全环境中执行操作
runtime.execute(|| {
// 这里可以安全地处理受保护的数据
let mut secret = secret.borrow_mut();
// 执行加密操作等
secret[0] = b'S';
Ok(())
})?;
Ok(())
}
高级用法
自定义加密策略
use stronghold_runtime::{Stronghold, Location, CryptoProvider};
use ring::aead;
struct CustomCrypto;
impl CryptoProvider for CustomCrypto {
fn encrypt(&self, data: &[u8], key: &[u8]) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
// 实现自定义加密逻辑
Ok(data.to_vec()) // 示例中简单返回原数据
}
fn decrypt(&self, data: &[u8], key: &[u8]) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
// 实现自定义解密逻辑
Ok(data.to_vec()) // 示例中简单返回原数据
}
}
fn custom_crypto_example() -> Result<(), Box<dyn std::error::Error>> {
let crypto = CustomCrypto;
let mut stronghold = Stronghold::with_crypto(crypto);
let location = Location::generic("custom", "data");
stronghold.store(location.clone(), b"custom encrypted data".to_vec())?;
Ok(())
}
内存保护示例
use stronghold_runtime::Protected;
fn memory_protection_example() {
// 创建受保护的内存区域
let protected_data = Protected::new(vec![1, 2, 3, 4, 5]);
// 访问数据
{
let data = protected_data.borrow();
println!("Protected data: {:?}", *data);
}
// 修改数据
{
let mut data = protected_data.borrow_mut();
data[0] = 10;
}
// 数据离开作用域时会自动清零
}
完整示例demo
以下是一个结合了基本使用和高级特性的完整示例:
use stronghold_runtime::{Stronghold, Location, SecureRuntime, Protected, CryptoProvider};
use std::error::Error;
// 自定义加密策略实现
struct AesGcmCrypto;
impl CryptoProvider for AesGcmCrypto {
fn encrypt(&self, data: &[u8], key: &[u8]) -> Result<Vec<u8>, Box<dyn Error>> {
// 实际项目中应该实现AES-GCM加密
// 这里简化为示例
Ok(data.to_vec())
}
fn decrypt(&self, data: &[u8], key: &[u8]) -> Result<Vec<u8>, Box<dyn Error>> {
// 实际项目中应该实现AES-GCM解密
// 这里简化为示例
Ok(data.to_vec())
}
}
fn main() -> Result<(), Box<dyn Error>> {
// 1. 使用自定义加密策略创建Stronghold实例
let crypto = AesGcmCrypto;
let mut stronghold = Stronghold::with_crypto(crypto);
// 2. 存储敏感数据
let user_credentials = Location::generic("auth", "user_credentials");
stronghold.store(
user_credentials.clone(),
b"encrypted_user:password".to_vec()
)?;
// 3. 检索数据
if let Some(data) = stronghold.retrieve(&user_credentials)? {
println!("Retrieved credentials: {:?}", data);
}
// 4. 使用安全运行时处理敏感数据
let runtime = SecureRuntime::new()?;
let secret_key = Protected::new(b"super_secret_key".to_vec());
runtime.execute(|| {
let mut key = secret_key.borrow_mut();
// 在安全环境中处理密钥
key[0] = b'K';
Ok(())
})?;
// 5. 内存保护演示
{
let sensitive_data = Protected::new(vec![1, 2, 3, 4, 5]);
let data = sensitive_data.borrow();
println!("Sensitive data: {:?}", *data);
} // 离开作用域后数据会自动清零
Ok(())
}
最佳实践
- 总是使用
Protected
类型处理敏感数据 - 定期轮换加密密钥
- 最小化数据在内存中的暴露时间
- 使用不同的
Location
路径隔离不同敏感级别的数据 - 在生产环境中使用强密码学实现替代示例中的简单实现
注意事项
- stronghold-runtime仍在积极开发中,API可能会有变动
- 确保妥善保管加密密钥
- 在生产环境中使用前进行充分的安全审计