Rust加密库fernet的使用,Fernet提供简单安全的对称加密功能,支持消息认证和时间戳验证
Rust加密库fernet的使用
Fernet提供简单安全的对称加密功能,支持消息认证和时间戳验证
什么是Fernet?
Fernet是一个小型库,帮助您加密带有可选过期时间的数据包。它非常适合用于令牌或在两点之间交换小字符串或数据块。Fernet设计为易于使用,结合了密码学原语,使其难以出错,防止篡改,并让您确信令牌是合法的。
典型使用场景
- URL或授权头中的时间限制认证令牌
- 使用静态密钥在两个点之间发送小的加密数据块
- 简单加密秘密以存储到磁盘,稍后可读取
- 其他需要简单安全加密的场景
基本使用方法
- 首先在Cargo.toml中添加依赖:
[dependencies]
fernet = "0.1"
- 完整示例代码:
use fernet::Fernet;
use std::time::{SystemTime, UNIX_EPOCH};
fn main() {
// 1. 生成Fernet密钥
let key = Fernet::generate_key();
let fernet = Fernet::new(&key).unwrap();
// 2. 准备要加密的消息
let message = "这是需要加密的秘密数据";
// 3. 加密消息
let encrypted = fernet.encrypt(message.as_bytes());
println!("加密结果: {}", encrypted);
// 4. 解密消息
let decrypted = fernet.decrypt(&encrypted).unwrap();
let decrypted_str = String::from_utf8(decrypted).unwrap();
println!("解密结果: {}", decrypted_str);
}
高级功能 - 时间控制加密
如果需要测试令牌过期功能,可以使用特定时间加密/解密:
- 修改Cargo.toml启用特殊功能:
[dependencies]
fernet = { version = "0.1", features = ["fernet_danger_timestamps"] }
- 使用示例:
#[cfg(feature = "fernet_danger_timestamps")]
{
let current_time = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs();
// 模拟1小时前的加密
let past_time = current_time - 3600;
let encrypted_past = fernet.encrypt_at_time(message.as_bytes(), past_time);
match fernet.decrypt_at_time(&encrypted_past, current_time) {
Ok(decrypted) => println!("解密成功"),
Err(e) => println!("解密失败: {}", e),
}
}
注意事项
- Fernet适合加密小数据块,不适合大文件加密
- 默认情况下令牌有效期是60秒
- 使用时间控制功能需要明确启用
fernet_danger_timestamps
特性 - 密钥需要安全保存,泄露密钥会导致加密数据被破解
1 回复
Rust加密库fernet使用指南
Fernet是一个提供简单安全对称加密功能的Rust库,支持消息认证和时间戳验证。它基于AES-128-CBC加密和HMAC-SHA256认证,确保数据的机密性和完整性。
安装方法
在Cargo.toml中添加依赖:
[dependencies]
fernet = "0.2"
基本使用方法
1. 生成密钥
use fernet::Fernet;
let key = Fernet::generate_key();
println!("Generated key: {}", key);
2. 加密数据
use fernet::Fernet;
let key = Fernet::generate_key();
let fernet = Fernet::new(&key).unwrap();
let message = "This is a secret message";
let encrypted = fernet.encrypt(message.as_bytes());
println!("Encrypted: {}", encrypted);
3. 解密数据
use fernet::Fernet;
let key = "your_fernet_key_here";
let fernet = Fernet::new(key).unwrap();
let encrypted = "encrypted_token_here";
let decrypted = fernet.decrypt(encrypted).unwrap();
println!("Decrypted: {}", String::from_utf8(decrypted).unwrap());
高级功能
带TTL验证的解密
use fernet::Fernet;
use std::time::Duration;
let key = Fernet::generate_key();
let fernet = Fernet::new(&key).unwrap();
let message = "Time-sensitive message";
let encrypted = fernet.encrypt(message.as_bytes());
// 解密时验证消息是否在30秒内创建
match fernet.decrypt_with_ttl(&encrypted, Duration::from_secs(30)) {
Ok(decrypted) => println!("Valid message: {}", String::from_utf8(decrypted).unwrap()),
Err(e) => println!("Decryption failed: {}", e),
}
加密结构体
use fernet::Fernet;
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
struct UserData {
id: u64,
username: String,
email: String,
}
let key = Fernet::generate_key();
let fernet = Fernet::new(&key).unwrap();
let user = UserData {
id: 42,
username: "example".to_string(),
email: "user@example.com".to_string(),
};
// 序列化并加密
let serialized = serde_json::to_vec(&user).unwrap();
let encrypted = fernet.encrypt(&serialized);
// 解密并反序列化
let decrypted = fernet.decrypt(&encrypted).unwrap();
let user: UserData = serde_json::from_slice(&decrypted).unwrap();
println!("Decrypted user: {} ({})", user.username, user.email);
安全注意事项
- 密钥应该安全存储,不要硬编码在代码中
- 对于生产环境,考虑使用密钥管理系统
- 定期轮换密钥
- 对于非常敏感的数据,考虑使用非对称加密
Fernet提供了一种简单但安全的方式来加密数据,特别适合需要消息认证和时间敏感验证的场景。
完整示例
下面是一个完整的示例,展示了Fernet库的主要功能:
use fernet::Fernet;
use serde::{Serialize, Deserialize};
use std::time::Duration;
#[derive(Serialize, Deserialize, Debug)]
struct SecretMessage {
sender: String,
content: String,
timestamp: i64,
}
fn main() {
// 1. 生成密钥
let key = Fernet::generate_key();
println!("Generated key: {}", key);
// 2. 创建Fernet实例
let fernet = Fernet::new(&key).unwrap();
// 3. 准备要加密的数据
let secret = SecretMessage {
sender: "Alice".to_string(),
content: "Meet me at 5pm".to_string(),
timestamp: chrono::Utc::now().timestamp(),
};
// 4. 序列化并加密数据
let serialized = serde_json::to_vec(&secret).unwrap();
let encrypted = fernet.encrypt(&serialized);
println!("Encrypted message: {}", encrypted);
// 5. 解密数据(无TTL验证)
let decrypted = fernet.decrypt(&encrypted).unwrap();
let secret: SecretMessage = serde_json::from_slice(&decrypted).unwrap();
println!("Decrypted message: {:?}", secret);
// 6. 带TTL验证的解密
match fernet.decrypt_with_ttl(&encrypted, Duration::from_secs(30)) {
Ok(decrypted) => {
let secret: SecretMessage = serde_json::from_slice(&decrypted).unwrap();
println!("Valid message: {:?}", secret);
}
Err(e) => println!("Message expired or invalid: {}", e),
}
}
这个示例展示了:
- 密钥生成
- 结构体序列化
- 数据加密
- 基本解密
- 带TTL验证的解密
要运行此示例,需要在Cargo.toml中添加以下依赖:
[dependencies]
fernet = "0.2"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
chrono = "0.4"