相关依赖
[dependencies]
md-5 = "0.10.6" # 如果你需要MD5哈希
serde_json = "1.0.141"
cipher = "0.4.4"
aes = "0.8.4"
des = "0.8.1"
cbc = "0.1" # 替代 block-modes 的 CBC 实现
hex = "0.4" # 十六进制编码(测试用)
rand = "0.9.2"
hex-literal = "1.0.0"
bytes = "1.10.1"
anyhow = "1.0.98"
rsa = { version = "0.9.8", features = ["pem", "sha2"] }
sha2 = "0.10"
rand_chacha = "0.9.0"
des加解密
use aes::Aes128;
use cbc::{Decryptor, Encryptor};
use cipher::block_padding::Pkcs7;
use cipher::{BlockDecryptMut, BlockEncryptMut, KeyInit, KeyIvInit, generic_array::GenericArray};
use anyhow::{Context, Result, bail};
// 类型别名简化代码
type Aes128CbcEnc = Encryptor<Aes128>;
type Aes128CbcDec = Decryptor<Aes128>;
const BLOCK_SIZE: usize = 16; // AES块大小固定16字节
/// AES-CBC解密
/// 参数:
/// - key: 与加密相同的密钥
/// - iv: 加密时返回的IV
/// - ciphertext: 密文数据
/// 返回: 解密后的明文
pub fn aes_cbc_decrypt_mut(key: &[u8], iv: &[u8], ciphertext: &[u8]) -> Result<Vec<u8>> {
if iv.len() != BLOCK_SIZE {
bail!("Invalid IV length: expected {} bytes", BLOCK_SIZE)
};
if ciphertext.is_empty() || ciphertext.len() % BLOCK_SIZE != 0 {
bail!("Invalid ciphertext length: must be non-empty and multiple of block size");
};
let mut buffer = ciphertext.to_vec();
let plaintext = Aes128CbcDec::new_from_slices(key, iv)
.context("Failed to create decryptor")?
.decrypt_padded_mut::<Pkcs7>(&mut buffer)
.map_err(|e| anyhow::anyhow!("Decryption error: {:?}", e))?;
Ok(plaintext.to_vec())
}
// pub fn aes_cbc_encrypt_mut<'a>(key: &[u8], iv: &[u8], plaintext: &[u8]) -> Result<Vec<u8>> {
// if iv.len() != BLOCK_SIZE {
// bail!("Invalid IV length: expected {} bytes", BLOCK_SIZE)
// };
// if plaintext.is_empty() || plaintext.len() % BLOCK_SIZE != 0 {
// bail!("Invalid ciphertext length: must be non-empty and multiple of block size");
// };
// let mut buffer = plaintext.to_vec();
// let ciphertext = Aes128CbcEnc::new_from_slices(key, iv)
// .context("failed encrypt")?
// .encrypt_padded_mut::<Pkcs7>(&mut buffer, plaintext.len())
// .map_err(|e| anyhow::anyhow!("Encryption error: {:?}", e))?
// .to_vec();
// Ok(ciphertext)
// }
pub fn aes_cbc_encrypt(key: &[u8], iv: &[u8], plaintext: &[u8]) -> Result<Vec<u8>> {
if iv.len() != BLOCK_SIZE {
bail!("Invalid IV length: expected {} bytes", BLOCK_SIZE);
}
if plaintext.is_empty() {
bail!("Plaintext cannot be empty");
}
// 创建足够大的缓冲区(明文长度 + 可能的填充)
let mut buffer = vec![0u8; plaintext.len() + BLOCK_SIZE];
buffer[..plaintext.len()].copy_from_slice(plaintext);
let ciphertext = Aes128CbcEnc::new_from_slices(key, iv)
.context("Failed to create encryptor")?
.encrypt_padded_mut::<Pkcs7>(
&mut buffer, // 第一个参数:缓冲区
plaintext.len(), // 第二个参数:明文长度
)
.map_err(|e| anyhow::anyhow!("Encryption error: {:?}", e))?;
Ok(ciphertext.to_vec())
}
des加解密
use cbc::{Decryptor, Encryptor};
use cipher::block_padding::Pkcs7;
use cipher::{BlockDecrypt, BlockDecryptMut, BlockEncryptMut, KeyInit, KeyIvInit, block_padding};
use des::Des;
// 对应 Python 的 DES.new("abcd1234", DES.MODE_CBC, iv="12345678")
fn des_cbc_encrypt(key: &[u8], iv: &[u8], plaintext: &[u8]) -> Vec<u8> {
let mut buffer = vec![0u8; plaintext.len() + 8]; // DES 块大小是8字节
buffer[..plaintext.len()].copy_from_slice(plaintext);
Encryptor::<Des>::new_from_slices(key, iv)
.unwrap()
.encrypt_padded_mut::<Pkcs7>(&mut buffer, plaintext.len())
.unwrap()
.to_vec()
}
pub fn des_cbc_decrypt(key: &[u8], iv: &[u8], ciphertext: &[u8]) -> Vec<u8> {
let mut buffer = ciphertext.to_vec();
Decryptor::<Des>::new_from_slices(key, iv)
.unwrap()
.decrypt_padded_mut::<Pkcs7>(&mut buffer)
.unwrap()
.to_vec()
}
rsa加解密
use rsa::{
RsaPrivateKey, RsaPublicKey,
pkcs1::{EncodeRsaPrivateKey, EncodeRsaPublicKey, DecodeRsaPrivateKey, DecodeRsaPublicKey, LineEnding},
Pkcs1v15Encrypt, Oaep, Pkcs1v15Sign, Pss
};
use sha2::Sha256;
use rand::rngs::OsRng;
use std::fs;
/// 生成 RSA 密钥对并保存为 PEM 文件
pub fn generate_and_save_keys(
private_key_path: &str,
public_key_path: &str,
bits: usize,
) -> Result<(), Box<dyn std::error::Error>> {
let mut rng = OsRng;
let private_key = RsaPrivateKey::new(&mut rng, bits)?;
let public_key = RsaPublicKey::from(&private_key);
// 保存私钥 (PKCS#1 PEM 格式)
let pem_private = private_key.to_pkcs1_pem(LineEnding::LF)?;
fs::write(private_key_path, pem_private.as_bytes())?;
// 保存公钥 (PKCS#1 PEM 格式)
let pem_public = public_key.to_pkcs1_pem(LineEnding::LF)?;
fs::write(public_key_path, pem_public.as_bytes())?;
Ok(())
}
/// 从 PEM 文件加载私钥
pub fn load_private_key(path: &str) -> Result<RsaPrivateKey, Box<dyn std::error::Error>> {
let pem = fs::read_to_string(path)?;
Ok(RsaPrivateKey::from_pkcs1_pem(&pem)?)
}
/// 从 PEM 文件加载公钥
pub fn load_public_key(path: &str) -> Result<RsaPublicKey, Box<dyn std::error::Error>> {
let pem = fs::read_to_string(path)?;
Ok(RsaPublicKey::from_pkcs1_pem(&pem)?)
}
/// RSA 加密 (PKCS#1 v1.5 填充)
pub fn encrypt_pkcs1v15(
public_key: &RsaPublicKey,
data: &[u8],
) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
let mut rng = OsRng;
Ok(public_key.encrypt(&mut rng, Pkcs1v15Encrypt, data)?)
}
/// RSA 加密 (OAEP 填充 - 推荐)
pub fn encrypt_oaep(
public_key: &RsaPublicKey,
data: &[u8],
) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
let mut rng = OsRng;
let padding = Oaep::new::<Sha256>();
Ok(public_key.encrypt(&mut rng, padding, data)?)
}
/// RSA 解密 (PKCS#1 v1.5)
pub fn decrypt_pkcs1v15(
private_key: &RsaPrivateKey,
ciphertext: &[u8],
) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
Ok(private_key.decrypt(Pkcs1v15Encrypt, ciphertext)?)
}
/// RSA 解密 (OAEP)
pub fn decrypt_oaep(
private_key: &RsaPrivateKey,
ciphertext: &[u8],
) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
let padding = Oaep::new::<Sha256>();
Ok(private_key.decrypt(padding, ciphertext)?)
}
/// RSA 签名 (PKCS#1 v1.5)
pub fn sign_pkcs1v15(
private_key: &RsaPrivateKey,
data: &[u8],
) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
let padding = Pkcs1v15Sign::new::<Sha256>();
Ok(private_key.sign(padding, data)?)
}
/// RSA 签名 (PSS - 推荐)
pub fn sign_pss(
private_key: &RsaPrivateKey,
data: &[u8],
) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
let padding = Pss::new::<Sha256>();
Ok(private_key.sign(padding, data)?)
}
/// 验证签名 (PKCS#1 v1.5)
pub fn verify_pkcs1v15(
public_key: &RsaPublicKey,
data: &[u8],
signature: &[u8],
) -> Result<(), Box<dyn std::error::Error>> {
let padding = Pkcs1v15Sign::new::<Sha256>();
public_key.verify(padding, data, signature)?;
Ok(())
}
/// 验证签名 (PSS)
pub fn verify_pss(
public_key: &RsaPublicKey,
data: &[u8],
signature: &[u8],
) -> Result<(), Box<dyn std::error::Error>> {
let padding = Pss::new::<Sha256>();
public_key.verify(padding, data, signature)?;
Ok(())
}
目前还没有做测试,有时间再做,打会儿文明六先…