Rust流密码库stream-cipher的使用:高效实现对称加密算法的加密与解密功能

🚨 已弃用! 🚨

block-cipherstream-cipher 库已经合并到新的 cipher 库中。

block-cipherstream-cipher 将不再发布新版本。

请升级到 cipher 库:

以下是使用 stream-cipher 库实现对称加密的完整示例代码:

use stream_cipher::{
    generic_array::GenericArray,
    NewStreamCipher, SyncStreamCipher, SyncStreamCipherSeek
};

// 使用 ChaCha20 算法示例
type ChaCha20 = chacha20::ChaCha20;

fn main() {
    // 密钥和随机数(nonce)
    let key = GenericArray::from_slice(b"very long secret key");
    let nonce = GenericArray::from_slice(b"unique nonce");
    
    // 创建加密器实例
    let mut cipher = ChaCha20::new(key, nonce);
    
    // 要加密的数据
    let mut data = *b"hello world!";
    
    // 加密数据
    cipher.apply_keystream(&mut data);
    println!("密文: {:?}", &data);
    
    // 重置状态到初始位置进行解密
    cipher.seek(0);
    cipher.apply_keystream(&mut data);
    println!("明文: {:?}", &data);
}

代码说明:

  1. 使用 GenericArray 创建密钥和随机数
  2. 初始化 ChaCha20 流密码实例
  3. apply_keystream 方法同时用于加密和解密
  4. seek(0) 将流密码重置到初始状态进行解密

注意:此代码仅为示例,实际使用时请参考最新的 cipher 库文档,并确保使用安全的密钥管理实践。

以下是使用新版 cipher 库的完整示例代码:

use cipher::{
    generic_array::GenericArray,
    NewCipher, StreamCipher, StreamCipherSeek
};

// 使用 ChaCha20 算法示例
type ChaCha20 = chacha20::ChaCha20;

fn main() {
    // 密钥和随机数(nonce)
    let key = GenericArray::from_slice(b"very long secret key");
    let nonce = GenericArray::from_slice(b"unique nonce");
    
    // 创建加密器实例
    let mut cipher = ChaCha20::new(key, nonce);
    
    // 要加密的数据
    let mut data = *b"hello world!";
    
    // 加密数据
    cipher.apply_keystream(&mut data);
    println!("密文: {:?}", &data);
    
    // 重置状态到初始位置进行解密
    cipher.seek(0);
    cipher.apply_keystream(&mut data);
    println!("明文: {:?}", &data);
}

新版代码主要变化:

  1. 使用 cipher crate 替代了原来的 stream_cipher
  2. trait 名称从 NewStreamCipher 改为 NewCipher
  3. trait 名称从 SyncStreamCipher 改为 StreamCipher
  4. trait 名称从 SyncStreamCipherSeek 改为 StreamCipherSeek

功能和使用方法与旧版保持兼容,建议尽快迁移到新版本。


1 回复

Rust流密码库stream-cipher使用指南

概述

stream-cipher是Rust中一个通用的流密码(trait)接口库,提供了对称加密算法的统一抽象接口。它支持多种流密码算法实现,如ChaCha20、Salsa20等。

主要特性

  • 统一的流密码trait接口
  • 支持多种流行流密码算法
  • 零成本抽象
  • 符合Rust的加密库安全实践

使用方法

添加依赖

首先在Cargo.toml中添加依赖:

[dependencies]
stream-cipher = "0.7"

基本加密/解密示例

use stream_cipher::{NewStreamCipher, SyncStreamCipher};
use stream_cipher::generic_array::GenericArray;

// 选择具体的流密码算法(这里以ChaCha20为例)
use chacha20::ChaCha20;

fn main() {
    // 密钥和nonce(一次性数字)
    let key = GenericArray::from_slice(b"very secret key very secret key");
    let nonce = GenericArray::from_slice(b"unique nonce");
    
    // 创建加密器实例
    let mut cipher = ChaCha20::new(key, nonce);
    
    // 要加密的数据
    let mut data = *b"hello world! this is a secret message";
    
    // 加密数据(原地操作)
    cipher.apply_keystream(&mut data);
    println!("加密后: {:?}", &data);
    
    // 为了解密,需要重新创建相同参数的加密器
    let mut cipher = ChaCha20::new(key, nonce);
    
    // 解密数据
    cipher.apply_keystream(&mut data);
    println!("解密后: {:?}", std::str::from_utf8(&data).unwrap());
}

使用不同的流密码算法

use salsa20::Salsa20;
use stream_cipher::{NewStreamCipher, SyncStreamCipher};
use stream_cipher::generic_array::GenericArray;

fn salsa_example() {
    let key = GenericArray::from_slice(b"an example very very secret key.");
    let nonce = GenericArray::from_slice(b"unique nonce");
    
    let mut cipher = Salsa20::new(key, nonce);
    
    let mut data = *b"hello salsa!";
    cipher.apply_keystream(&mut data);
    
    println!("Salsa20加密后: {:?}", &data);
    
    // 解密
    let mut cipher = Salsa20::new(key, nonce);
    cipher.apply_keystream(&mut data);
    println!("Salsa20解密后: {}", std::str::from_utf8(&data).unwrap());
}

注意事项

  1. Nonce安全性:每次加密必须使用唯一的nonce,重复使用nonce会破坏安全性
  2. 密钥管理:密钥需要安全存储,不要硬编码在源代码中
  3. 算法选择:根据安全需求选择合适的算法,ChaCha20通常比Salsa20更推荐

高级用法

分段处理数据

对于大文件或流数据,可以分段处理:

use chacha20::ChaCha20;
use stream_cipher::{NewStreamCipher, SyncStreamCipher};

fn process_large_data() {
    let key = [0x42; 32];
    let nonce = [0x24; 12];
    let mut cipher = ChaCha20::new(&key.into(), &nonce.into());
    
    let mut chunk1 = [1, 2, 3, 4, 5];
    let mut chunk2 = [6, 7, 8, 9, 10];
    
    cipher.apply_keystream(&mut chunk1);
    cipher.apply_keystream(&mut chunk2);
    
    // 解密时需要从相同状态继续
}

使用随机nonce

use rand_core::{OsRng, RngCore};
use chacha20::ChaCha20;

fn random_nonce_example() {
    let mut key = [0u8; 32];
    let mut nonce = [0u8; 12];
    
    OsRng.fill_bytes(&mut key);
    OsRng.fill_bytes(&mut nonce);
    
    let mut cipher = ChaCha20::new(&key.into(), &nonce.into());
    // ... 其余加密逻辑
}

支持的算法

stream-cipher作为trait库,需要配合具体算法实现使用,常见的有:

  • chacha20: ChaCha20流密码
  • salsa20: Salsa20流密码
  • aes: AES-CTR模式(作为流密码使用)

通过统一的trait接口,可以在不同算法间轻松切换,而无需修改核心加密逻辑。

完整示例代码

// 完整示例:使用ChaCha20加密/解密文件内容
use std::fs::File;
use std::io::{Read, Write};
use chacha20::ChaCha20;
use stream_cipher::{NewStreamCipher, SyncStreamCipher};
use stream_cipher::generic_array::GenericArray;
use rand_core::{OsRng, RngCore};

fn main() -> std::io::Result<()> {
    // 1. 生成随机密钥和nonce
    let mut key = [0u8; 32]; // ChaCha20需要32字节密钥
    let mut nonce = [0u8; 12]; // 12字节nonce
    OsRng.fill_bytes(&mut key);
    OsRng.fill_bytes(&mut nonce);
    
    // 2. 加密文件
    encrypt_file("plaintext.txt", "ciphertext.bin", &key, &nonce)?;
    
    // 3. 解密文件
    decrypt_file("ciphertext.bin", "decrypted.txt", &key, &nonce)?;
    
    Ok(())
}

fn encrypt_file(
    input_path: &str, 
    output_path: &str,
    key: &[u8; 32],
    nonce: &[u8; 12]
) -> std::io::Result<()> {
    // 读取文件内容
    let mut file = File::open(input_path)?;
    let mut buffer = Vec::new();
    file.read_to_end(&mut buffer)?;
    
    // 创建加密器
    let key = GenericArray::from_slice(key);
    let nonce = GenericArray::from_slice(nonce);
    let mut cipher = ChaCha20::new(key, nonce);
    
    // 原地加密
    cipher.apply_keystream(&mut buffer);
    
    // 写入加密后文件
    let mut output = File::create(output_path)?;
    output.write_all(&buffer)?;
    
    println!("文件加密完成: {}", output_path);
    Ok(())
}

fn decrypt_file(
    input_path: &str, 
    output_path: &str,
    key: &[u8; 32],
    nonce: &[u8; 12]
) -> std::io::Result<()> {
    // 读取加密文件
    let mut file = File::open(input_path)?;
    let mut buffer = Vec::new();
    file.read_to_end(&mut buffer)?;
    
    // 创建解密器(使用相同密钥和nonce)
    let key = GenericArray::from_slice(key);
    let nonce = GenericArray::from_slice(nonce);
    let mut cipher = ChaCha20::new(key, nonce);
    
    // 原地解密
    cipher.apply_keystream(&mut buffer);
    
    // 写入解密后文件
    let mut output = File::create(output_path)?;
    output.write_all(&buffer)?;
    
    println!("文件解密完成: {}", output_path);
    Ok(())
}
回到顶部