rust实现的一些加密算法

2025-07-20

相关依赖

[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(())
}

目前还没有做测试,有时间再做,打会儿文明六先…