Rust数据安全加密库self_encryption的使用:实现高效自加密与分布式存储数据保护
Rust数据安全加密库self_encryption的使用:实现高效自加密与分布式存储数据保护
self_encryption
自加密文件(收敛加密加混淆)
概述
一种带有额外混淆步骤的收敛加密版本。这种模式允许安全数据同时可以进行去重。本库提供了一个API,接收一组字节并返回从这些字节派生的秘密密钥,以及一组加密的块。
重要安全说明:虽然这个库提供了非常安全的数据加密,但返回的秘密密钥需要与任何秘密密钥相同的安全处理。
特性
- 基于内容的分块
- 收敛加密
- 自验证块
- 处理大文件的分层数据映射
- 流式加密/解密
- Python绑定
- 灵活的存储后端支持
- 通过函子自定义存储后端
使用
Rust使用
安装
在Cargo.toml
中添加:
[dependencies]
self_encryption = "0.30"
bytes = "1.0"
基本操作
use self_encryption::{encrypt, decrypt_full_set};
use bytes::Bytes;
// 基本加密/解密
fn basic_example() -> Result<()> {
let data = Bytes::from("Hello, World!".repeat(1000)); // 必须至少3072字节
// 加密数据
let (data_map, encrypted_chunks) = encrypt(data.clone())?;
// 解密数据
let decrypted = decrypt_full_set(&data_map, &encrypted_chunks)?;
assert_eq!(data, decrypted);
Ok(())
}
存储后端
use self_encryption::{shrink_data_map, get_root_data_map, decrypt_from_storage};
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
// 内存存储示例
fn memory_storage_example() -> Result<()> {
let storage = Arc::new(Mutex::new(HashMap::new()));
// 存储函数
let store = |hash, data| {
storage.lock().unwrap().insert(hash, data);
Ok(())
};
// 检索函数
let retrieve = |hash| {
storage.lock().unwrap()
.get(&hash)
.cloned()
.ok_or_else(|| Error::Generic("Chunk not found".into()))
};
// 使用数据映射操作
let shrunk_map = shrink_data_map(data_map, store)?;
let root_map = get_root_data_map(shrunk_map, retrieve)?;
Ok(())
}
// 磁盘存储示例
fn disk_storage_example() -> Result<()> {
let chunk_dir = PathBuf::from("chunks");
// 存储函数
let store = |hash, data| {
let path = chunk_dir.join(hex::encode(hash));
std::fs::write(path, data)?;
Ok(())
};
// 检索函数
let retrieve = |hash| {
let path = chunk_dir.join(hex::encode(hash));
Ok(Bytes::from(std::fs::read(path)?))
};
// 使用数据映射操作
let shrunk_map = shrink_data_map(data_map, store)?;
let root_map = get_root_data_map(shrunk_map, retrieve)?;
Ok(())
}
完整示例代码
use self_encryption::{encrypt, decrypt_full_set, shrink_data_map, get_root_data_map};
use bytes::Bytes;
use std::collections::HashMap;
use std::path::PathBuf;
use std::sync::{Arc, Mutex};
use std::fs;
// 完整示例展示自加密、解密和不同存储后端的使用
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 1. 基本加密/解密示例
println!("Running basic encryption/decryption example...");
let data = Bytes::from("Self-encryption example data".repeat(100));
let (data_map, encrypted_chunks) = encrypt(data.clone())?;
let decrypted = decrypt_full_set(&data_map, &encrypted_chunks)?;
assert_eq!(data, decrypted);
println!("Basic example completed successfully!");
// 2. 内存存储示例
println!("\nRunning in-memory storage example...");
let storage = Arc::new(Mutex::new(HashMap::new()));
let store = |hash: Vec<u8>, data: Bytes| {
storage.lock().unwrap().insert(hash, data);
Ok(())
};
let retrieve = |hash: Vec<u8>| {
storage.lock().unwrap()
.get(&hash)
.cloned()
.ok_or_else(|| self_encryption::Error::Generic("Chunk not found".into()))
};
let shrunk_map = shrink_data_map(data_map.clone(), store)?;
let _root_map = get_root_data_map(shrunk_map, retrieve)?;
println!("In-memory storage example completed!");
// 3. 磁盘存储示例
println!("\nRunning disk storage example...");
let chunk_dir = PathBuf:: from("self_encryption_chunks");
fs::create_dir_all(&chunk_dir)?;
let store_disk = |hash: Vec<u8>, data: Bytes| {
let path = chunk_dir.join(hex::encode(hash));
fs::write(path, data)?;
Ok(())
};
let retrieve_disk = |hash: Vec<u8>| {
let path = chunk_dir.join(hex::encode(hash));
Ok(Bytes::from(fs::read(path)?))
};
let shrunk_map_disk = shrink_data_map(data_map, store_disk)?;
let _root_map_disk = get_root_data_map(shrunk_map_disk, retrieve_disk)?;
println!("Disk storage example completed!");
Ok(())
}
实现细节
核心流程
- 文件被分割成最多1MB的块
- 每个块经过三个步骤处理:
- 压缩(使用Brotli)
- 加密(使用AES-256-CBC)
- XOR混淆
密钥生成和安全
-
每个块的加密使用从三个块的内容哈希派生的密钥:
对于块N: - 使用块[N, N+1, N+2]的哈希 - 组合哈希 = hash(N) || hash(N+1) || hash(N+2) - 分割为: - 填充(前X字节) - 密钥(接下来16字节用于AES-256) - IV(最后16字节)
-
创建了一个依赖链,其中每个块的加密依赖于其邻居
-
通过收敛加密和依赖关系提供额外的安全性
许可证
根据通用公共许可证(GPL)第3版授权,带有链接例外。这意味着你可以从任何程序(专有或开源)链接和使用该库;付费或免费。但是,如果你修改self_encryption,你必须根据GPLv3的条款分发修改版本的源代码。
1 回复
Rust数据安全加密库self_encryption的使用:实现高效自加密与分布式存储数据保护
介绍
self_encryption是一个Rust实现的加密库,专门为分布式存储系统设计,提供高效的自加密功能。它可以将数据分块并分别加密,使得每个数据块都可以独立解密,同时保持整体数据的安全性。
主要特点:
- 将大文件分割成多个加密块
- 每个块使用不同的密钥加密
- 提供完整性验证机制
- 适合分布式存储场景
- 零知识加密原则(服务端无法获取原始数据)
使用方法
添加依赖
首先在Cargo.toml中添加依赖:
[dependencies]
self_encryption = "0.10"
基本使用示例
use self_encryption::{SelfEncryptor, Storage};
use std::io::Cursor;
// 实现一个简单的内存存储
struct MemoryStorage {
data: Vec::u8,
}
impl Storage for MemoryStorage {
fn get(&self, _name: &str) -> Option<Vec<u8>> {
Some(self.data.clone())
}
fn put(&mut self, _name: &str, data: Vec<u8>) {
self.data = data;
}
}
fn main() {
// 准备要加密的数据
let data = b"这是一些需要加密的敏感数据";
// 创建内存存储和加密器
let mut storage = MemoryStorage { data: Vec::new() };
let mut encryptor = SelfEncryptor::new(&mut storage);
// 写入并加密数据
encryptor.write_all(data).unwrap();
encryptor.close().unwrap();
// 现在数据已加密并存储在storage中
// 创建解密器读取数据
let mut decryptor = SelfEncryptor::new(&mut storage);
let mut decrypted = Vec::new();
decryptor.read_to_end(&mut decrypted).unwrap();
assert_eq!(decrypted.as_slice(), data);
println!("解密成功: {:?}", String::_from_utf8(decrypted).unwrap());
}
文件加密示例
use self_encryption::{SelfEncryptor, Storage};
use std::fs::{File, OpenOptions};
use std::io::{Read, Write};
use std::path::Path;
// 文件存储实现
struct FileStorage {
path: String,
}
impl Storage for FileStorage {
fn get(&self, name: &str) -> Option<Vec<u8>> {
let path = Path::new(&self.path).join(name);
std::fs::read(path).ok()
}
fn put(&mut self, name: &str, data: Vec<u8>) {
let path = Path::new(&self.path).join(name);
let mut file = OpenOptions::new()
.write(true)
.create(true)
.open(path)
.unwrap();
file.write_all(&data).unwrap();
}
}
fn encrypt_file(input_path: &str, output_dir: &str) {
// 创建文件存储
let mut storage = FileStorage {
path: output_dir.to_string(),
};
// 读取原始文件
let mut file = File::open(input_path).unwrap();
let mut buffer = Vec::new();
file.read_to_end(&mut buffer).unwrap();
// 加密文件
let mut encryptor = SelfEncryptor::new(&mut storage);
encryptor.write_all(&buffer).unwrap();
encryptor.close().unwrap();
println!("文件加密完成,加密块保存在: {}", output_dir);
}
fn decrypt_file(output_path: &str, input_dir: &str) {
// 创建文件存储
let mut storage = FileStorage {
path: input_dir.to_string(),
};
// 解密数据
let mut decryptor = SelfEncryptor::new(&mut storage);
let mut decrypted = Vec::new();
decryptor.read_to_end(&mut decrypted).unwrap();
// 写入解密后的文件
let mut file = File::create(output_path).unwrap();
file.write_all(&decrypted).unwrap();
println!("文件解密完成,保存到: {}", output_path);
}
高级用法
自定义块大小
use self_encryption::{SelfEncryptor, Storage, EncryptionConfig};
let config = EncryptionConfig {
min_chunk_size: 1024, // 最小块大小1KB
avg_chunk_size: 1024 * 4, // 平均块大小4KB
max_chunk_size: 1024 * 16, // 最大块大小16KB
};
let mut storage = MemoryStorage { data: Vec::new() };
let mut encryptor = SelfEncryptor::with_config(&mut storage, config);
分布式存储集成
self_encryption特别适合与分布式存储系统集成,以下是一个简化的示例:
use self_encryption::{SelfEncryptor, Storage};
use reqwest::blocking::Client;
struct DistributedStorage {
client: Client,
base_url: String,
}
impl Storage for DistributedStorage {
fn get(&self, name: &str) -> Option<Vec<u8>> {
let url = format!("{}/{}", self.base_url, name);
self.client.get(&url).send().ok()?.bytes().ok().map(|b| b.to_vec())
}
fn put(&mut self, name: &str, data: Vec<u8>) {
let url = format!("{}/{}", self.base_url, name);
let _ = self.client.put(&url).body(data).send();
}
}
async fn store_in_distributed_system(data: &[u8], base_url: &str) {
let client = Client::new();
let mut storage = DistributedStorage {
client,
base_url: base_url.to_string(),
};
let mut encryptor = SelfEncryptor::new(&mut storage);
encryptor.write_all(data).unwrap();
encryptor.close().unwrap();
}
完整示例代码
下面是一个完整的自包含示例,演示了如何使用self_encryption进行数据加密和解密:
use self_encryption::{SelfEncryptor, Storage, EncryptionConfig};
use std::io::{Read, Write};
// 自定义内存存储实现
struct SimpleMemoryStorage {
data_chunks: Vec<Vec<u8>>,
}
impl Storage for SimpleMemoryStorage {
fn get(&self, name: &str) -> Option<Vec<u8>> {
// 简单实现:按索引获取数据块
name.parse::<usize>().ok()
.and_then(|i| self.data_chunks.get(i))
.map(|data| data.clone())
}
fn put(&mut self, name: &str, data: Vec<u8>) {
// 简单实现:按索引存储数据块
if let Ok(i) = name.parse::<usize>() {
if i >= self.data_chunks.len() {
self.data_chunks.resize(i + 1, Vec::new());
}
self.data_chunks[i] = data;
}
}
}
fn main() {
// 示例1: 基本加密解密
basic_encryption_example();
// 示例2: 自定义块大小加密
custom_chunk_size_example();
// 示例3: 模拟分布式存储
distributed_storage_example();
}
fn basic_encryption_example() {
println!("\n=== 基本加密解密示例 ===");
// 创建内存存储
let mut storage = SimpleMemoryStorage { data_chunks: Vec::new() };
// 准备要加密的数据
let secret_data = b"这是一个非常重要的秘密数据";
// 加密数据
{
let mut encryptor = SelfEncryptor::new(&mut storage);
encryptor.write_all(secret_data).unwrap();
encryptor.close().unwrap();
}
println!("加密完成,生成{}个数据块", storage.data_chunks.len());
// 解密数据
let mut decrypted = Vec::new();
{
let mut decryptor = SelfEncryptor::new(&mut storage);
decryptor.read_to_end(&mut decrypted).unwrap();
}
assert_eq!(decrypted.as_slice(), secret_data);
println!("解密成功: {}", String::from_utf8_lossy(&decrypted));
}
fn custom_chunk_size_example() {
println!("\n=== 自定义块大小示例 ===");
// 创建内存存储
let mut storage = SimpleMemoryStorage { data_chunks: Vec::new() };
// 配置块大小
let config = EncryptionConfig {
min_chunk_size: 1024, // 1KB
avg_chunk_size: 1024 * 4, // 4KB
max_chunk_size: 1024 * 8, // 8KB
};
// 准备大一点的数据
let mut large_data = Vec::new();
for i in 0..5000 {
large_data.extend(format!("数据块 {} ", i).as_bytes());
}
// 使用自定义配置加密
{
let mut encryptor = SelfEncryptor::with_config(&mut storage, config);
encryptor.write_all(&large_data).unwrap();
encryptor.close().unwrap();
}
println!("加密完成,生成{}个自定义大小的数据块", storage.data_chunks.len());
// 解密验证
let mut decrypted = Vec::new();
{
let mut decryptor = SelfEncryptor::new(&mut storage);
decryptor.read_to_end(&mut decrypted).unwrap();
}
assert_eq!(decrypted, large_data);
println!("解密验证成功,数据长度: {} 字节", decrypted.len());
}
fn distributed_storage_example() {
println!("\n=== 分布式存储模拟示例 ===");
// 模拟分布式节点
let mut node1 = SimpleMemoryStorage { data_chunks: Vec::new() };
let mut node2 = SimpleMemoryStorage { data_chunks: Vec::new() };
// 模拟分布式存储 - 交替存储在两个节点上
struct DistributedStorage<'a> {
node1: &'a mut SimpleMemoryStorage,
node2: &'a mut SimpleMemoryStorage,
}
impl Storage for DistributedStorage<'_> {
fn get(&self, name: &str) -> Option<Vec<u8>> {
// 根据块ID的奇偶决定从哪个节点获取
if let Ok(i) = name.parse::<usize>() {
if i % 2 == 0 {
self.node1.get(name)
} else {
self.node2.get(name)
}
} else {
None
}
}
fn put(&mut self, name: &str, data: Vec<u8>) {
// 根据块ID的奇偶决定存储到哪个节点
if let Ok(i) = name.parse::<usize>() {
if i % 2 == 0 {
self.node1.put(name, data);
} else {
self.node2.put(name, data);
}
}
}
}
let mut distributed_storage = DistributedStorage {
node1: &mut node1,
node2: &mut node2,
};
// 加密数据
let data = b"这是一个分布式存储的测试数据";
{
let mut encryptor = SelfEncryptor::new(&mut distributed_storage);
encryptor.write_all(data).unwrap();
encryptor.close().unwrap();
}
println!("数据已分布式存储:");
println!("- 节点1存储了{}个块", node1.data_chunks.len());
println!("- 节点2存储了{}个块", node2.data_chunks.len());
// 解密数据
let mut decrypted = Vec::new();
{
let mut decryptor = SelfEncryptor::new(&mut distributed_storage);
decryptor.read_to_end(&mut decrypted).unwrap();
}
assert_eq!(decrypted.as_slice(), data);
println!("分布式解密成功: {}", String::from_utf8_lossy(&decrypted));
}
注意事项
- 密钥管理:self_encryption会自动处理加密密钥,但你需要安全地存储加密后的数据块
- 性能考虑:对于非常大的文件,建议使用流式处理而不是一次性读取全部数据
- 错误处理:实际应用中应该添加适当的错误处理逻辑
- 存储实现:根据你的实际存储后端实现Storage trait
self_encryption库为Rust开发者提供了一种高效、安全的数据自加密方案,特别适合需要分布式存储敏感数据的应用场景。