Rust数据加密插件库age的使用:安全高效的加密与解密工具
Rust数据加密插件库age的使用:安全高效的加密与解密工具
age是一个简单、现代且安全的文件加密库,具有小型显式密钥、无配置选项和UNIX风格的组合性特点。
安装
在您的Cargo.toml
中添加:
age = "0.11"
特性标志
armor
:启用ASCII装甲的age文件支持async
:启用异步API进行加密和解密cli-common
:为构建age CLI工具提供常用辅助函数ssh
:允许重用现有的SSH密钥文件进行age加密web-sys
:在WebAssembly目标上使用Performance计时器计算密码加密的工作因子unstable
:启用开发中的功能(无稳定性保证)
示例代码
以下是使用age进行加密和解密的完整示例:
use age::secrecy::Secret;
use age::{Encryptor, Decryptor};
use std::io::{Read, Write};
fn main() -> Result<(), age::AgeError> {
// 要加密的明文
let plaintext = "Hello, age!".as_bytes();
// 生成X25519密钥对
let key = age::x25519::Identity::generate();
let pubkey = key.to_public();
// 加密
let encryptor = Encryptor::with_recipients(vec![Box::new(pubkey)])
.expect("we provided a recipient");
let mut encrypted = vec![];
{
let mut writer = encryptor.wrap_output(&mut encrypted)?;
writer.write_all(plaintext)?;
writer.finish()?;
}
// 解密
let decryptor = match Decryptor::new(&encrypted[..])? {
Decryptor::Recipients(d) => d,
_ => unreachable!(),
};
let mut decrypted = vec![];
{
let mut reader = decryptor.decrypt(Secret::new(key))?;
reader.read_to_end(&mut decrypted)?;
}
assert_eq!(plaintext, decrypted.as_slice());
println!("Decrypted: {}", String::from_utf8_lossy(&decrypted));
Ok(())
}
完整示例demo
以下是一个更完整的示例,展示了如何使用age加密文件并保存到磁盘,然后再解密:
use age::secrecy::Secret;
use age::{Encryptor, Decryptor};
use std::fs::File;
use std::io::{Read, Write};
use std::path::Path;
fn main() -> Result<(), age::AgeError> {
// 生成X25519密钥对
let key = age::x25519::Identity::generate();
let pubkey = key.to_public();
// 要加密的文件路径
let plaintext_path = Path::new("plaintext.txt");
let encrypted_path = Path::new("encrypted.age");
let decrypted_path = Path::new("decrypted.txt");
// 创建测试文件
File::create(&plaintext_path)?.write_all(b"This is a secret message!")?;
// 加密文件
encrypt_file(&plaintext_path, &encrypted_path, &pubkey)?;
// 解密文件
decrypt_file(&encrypted_path, &decrypted_path, &key)?;
println!("File encryption and decryption completed successfully!");
Ok(())
}
fn encrypt_file(
input_path: &Path,
output_path: &Path,
pubkey: &age::x25519::Recipient,
) -> Result<(), age::AgeError> {
// 读取要加密的文件内容
let plaintext = std::fs::read(input_path)?;
// 创建加密器
let encryptor = Encryptor::with_recipients(vec![Box::new(pubkey.clone())])
.expect("we provided a recipient");
// 创建输出文件并加密内容
let mut encrypted = vec![];
{
let mut writer = encryptor.wrap_output(&mut encrypted)?;
writer.write_all(&plaintext)?;
writer.finish()?;
}
// 将加密数据写入文件
std::fs::write(output_path, encrypted)?;
Ok(())
}
fn decrypt_file(
input_path: &Path,
output_path: &Path,
key: &age::x25519::Identity,
) -> Result<(), age::AgeError> {
// 读取加密文件内容
let encrypted = std::fs::read(input_path)?;
// 创建解密器
let decryptor = match Decryptor::new(&encrypted[..])? {
Decryptor::Recipients(d) => d,
_ => unreachable!(),
};
// 解密内容
let mut decrypted = vec![];
{
let mut reader = decryptor.decrypt(Secret::new(key.clone()))?;
reader.read_to_end(&mut decrypted)?;
}
// 将解密数据写入文件
std::fs::write(output_path, decrypted)?;
Ok(())
}
许可证
age采用双重许可证:
- Apache License 2.0
- MIT license
贡献
除非您明确声明,否则任何贡献都将按上述双重许可证提交。
1 回复
Rust数据加密插件库age的使用:安全高效的加密与解密工具
介绍
age是一个简单、现代且安全的文件加密工具和库,由Filippo Valsorda开发。它专注于提供简单易用的API,同时保持高安全性。age的设计目标是成为GPG的现代替代品,具有以下特点:
- 基于现代加密标准(X25519, ChaCha20-Poly1305等)
- 极简的API设计
- 无主密钥概念,每个密钥对独立工作
- 支持基于密码的加密
- 小巧高效,适合嵌入到其他应用中
安装方法
在Cargo.toml中添加依赖:
[dependencies]
age = "0.9"
完整示例代码
use age::{Encryptor, Decryptor, Recipient};
use age::x25519::{Identity, Recipient as X25519Recipient};
use age::secrecy::Secret;
use std::fs::File;
use std::io::{Read, Write};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 示例1: 生成密钥对
let identity = Identity::generate();
let recipient = identity.to_public();
println!("Generated private key: {}", identity.to_string());
println!("Generated public key: {}", recipient.to_string());
// 示例2: 使用公钥加密数据
let encryptor = Encryptor::with_recipients(vec![Box::new(recipient.clone())])
.expect("failed to create encryptor");
let mut encrypted = vec![];
{
let mut writer = encryptor.wrap_output(&mut encrypted)?;
writer.write_all(b"Hello, age! This is a secret message.")?;
writer.finish()?;
}
// 示例3: 使用私钥解密数据
let decryptor = match Decryptor::new(&encrypted[..])? {
Decryptor::Recipients(d) => d,
_ => panic!("not recipients encrypted"),
};
let mut decrypted = vec![];
{
let mut reader = decryptor.decrypt(std::iter::once(&identity as &dyn age::Identity))?;
reader.read_to_end(&mut decrypted)?;
}
println!("Decrypted: {}", String::from_utf8(decrypted)?);
// 示例4: 使用密码加密
let password = Secret::new("my-super-secret-password".to_owned());
let mut passphrase_encrypted = vec![];
{
let encryptor = Encryptor::with_user_passphrase(password.clone());
let mut writer = encryptor.wrap_output(&mut passphrase_encrypted)?;
writer.write_all(b"Message encrypted with password")?;
writer.finish()?;
}
// 示例5: 使用密码解密
let decryptor = match Decryptor::new(&passphrase_encrypted[..])? {
Decryptor::Passphrase(d) => d,
_ => panic!("not passphrase encrypted"),
};
let mut passphrase_decrypted = vec![];
{
let mut reader = decryptor.decrypt(&password, None)?;
reader.read_to_end(&mut passphrase_decrypted)?;
}
println!("Passphrase decrypted: {}", String::from_utf8(passphrase_decrypted)?);
// 示例6: 加密文件
{
// 创建测试文件
let mut test_file = File::create("test_plain.txt")?;
test_file.write_all(b"This is a test file content")?;
let input_file = File::open("test_plain.txt")?;
let output_file = File::create("test_encrypted.age")?;
let encryptor = Encryptor::with_recipients(vec![Box::new(recipient)])
.expect("failed to create file encryptor");
let mut writer = encryptor.wrap_output(output_file)?;
let mut buffer = [0; 1024];
loop {
let bytes_read = input_file.read(&mut buffer)?;
if bytes_read == 0 {
break;
}
writer.write_all(&buffer[..bytes_read])?;
}
writer.finish()?;
}
// 示例7: 解密文件
{
let input_file = File::open("test_encrypted.age")?;
let output_file = File::create("test_decrypted.txt")?;
let decryptor = match Decryptor::new(input_file)? {
Decryptor::Recipients(d) => d,
_ => panic!("not recipients encrypted file"),
};
let mut reader = decryptor.decrypt(std::iter::once(&identity as &dyn age::Identity))?;
let mut buffer = [0; 1024];
loop {
let bytes_read = reader.read(&mut buffer)?;
if bytes_read == 0 {
break;
}
output_file.write_all(&buffer[..bytes_read])?;
}
}
Ok(())
}
代码说明
- 首先生成了X25519密钥对,包含公钥和私钥
- 使用公钥加密了一段文本数据
- 使用对应的私钥解密数据并验证
- 演示了基于密码的加密和解密过程
- 展示了如何加密和解密整个文件
注意事项
- 私钥需要妥善保管,一旦丢失将无法解密数据
- 使用密码加密时,密码强度直接影响安全性
- 生产环境中建议结合age的CLI工具进行密钥管理
- 该库不适合需要密钥撤销或轮换的场景
age提供了简单而强大的加密功能,非常适合需要轻量级加密解决方案的Rust应用程序。