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的块
  • 每个块经过三个步骤处理:
    1. 压缩(使用Brotli)
    2. 加密(使用AES-256-CBC)
    3. 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));
}

注意事项

  1. 密钥管理:self_encryption会自动处理加密密钥,但你需要安全地存储加密后的数据块
  2. 性能考虑:对于非常大的文件,建议使用流式处理而不是一次性读取全部数据
  3. 错误处理:实际应用中应该添加适当的错误处理逻辑
  4. 存储实现:根据你的实际存储后端实现Storage trait

self_encryption库为Rust开发者提供了一种高效、安全的数据自加密方案,特别适合需要分布式存储敏感数据的应用场景。

回到顶部