feat(crypt):完成3DES加密算法的工具函数。

This commit is contained in:
徐涛 2023-07-02 17:56:12 +08:00
parent 56fef4c3de
commit 551209d4f1
4 changed files with 134 additions and 5 deletions

View File

@ -12,10 +12,10 @@ Rust 中可以使用的常用辅助功能工具箱。主要配备以下功能:
- [x] No Padding
- [x] ZerosPadding
- [x] Pkcs7Padding
- [ ] 3DES-CBC 便捷加解密算法
- [ ] No Padding
- [ ] ZerosPadding
- [ ] Pkcs7Padding
- [x] 3DES-CBC 便捷加解密算法
- [x] No Padding
- [x] ZerosPadding
- [x] Pkcs7Padding
- [ ] RSA 加解密算法
- [ ] 1024 位长
- [ ] 2048 位长

View File

@ -4,7 +4,7 @@ use des::Des;
type DesEncryptor = cbc::Encryptor<Des>;
type DesDecryptor = cbc::Decryptor<Des>;
/// 利用Sha512生成24字节的密钥
/// 利用Sha512生成8字节的密钥
///
/// - `key` 原始密钥
fn generate_key<T: AsRef<[u8]>>(key: T) -> [u8; 8] {

View File

@ -2,6 +2,7 @@ use thiserror::Error;
pub mod aes;
pub mod des;
pub mod tdes;
pub enum Padding {
NoPadding,

128
src/encryption/tdes.rs Normal file
View File

@ -0,0 +1,128 @@
use cipher::{BlockDecryptMut, BlockEncryptMut, KeyIvInit};
use des::TdesEde3;
type TripleDesEncryptor = cbc::Encryptor<TdesEde3>;
type TripleDesDecryptor = cbc::Decryptor<TdesEde3>;
/// 利用Sha512生成8字节的密钥
///
/// - `key` 原始密钥
fn generate_key<T: AsRef<[u8]>>(key: T) -> [u8; 8] {
let mut hasher = hmac_sha256::Hash::new();
hasher.update(key);
let result = hasher.finalize();
let mut compressed_key = [0u8; 8];
for i in 0..8 {
compressed_key[i] = result[i];
for j in 1..4 {
compressed_key[i] ^= result[i + j * 8];
}
}
compressed_key
}
/// 使用指定的密钥和填充方式对数据进行加密。
/// 如果需要字符串形式的密文,可以配合使用`hex`或者`base64`等函数。
///
/// - `key` 密钥
/// - `padding` 填充方式
/// - `plain_data` 明文数据
pub fn encrypt<T: AsRef<[u8]>, D: AsRef<[u8]>>(
key: T,
padding: super::Padding,
plain_data: D,
) -> Vec<u8> {
let key = generate_key(key);
let encryptor = TripleDesEncryptor::new(key.as_slice().into(), &key.into());
let result = match padding {
super::Padding::NoPadding => encryptor
.encrypt_padded_vec_mut::<cipher::block_padding::NoPadding>(plain_data.as_ref()),
super::Padding::ZeroPadding => encryptor
.encrypt_padded_vec_mut::<cipher::block_padding::ZeroPadding>(plain_data.as_ref()),
super::Padding::Pkcs7Padding => {
encryptor.encrypt_padded_vec_mut::<cipher::block_padding::Pkcs7>(plain_data.as_ref())
}
};
result
}
/// 使用指定的密钥和填充方式对数据进行解密。
///
/// - `key` 密钥
/// - `padding` 填充方式
/// - `cipher_data` 密文数据
pub fn decrypt<T: AsRef<[u8]>, D: AsRef<[u8]>>(
key: T,
padding: super::Padding,
cipher_data: D,
) -> Result<Vec<u8>, super::DecryptFailedError> {
let key = generate_key(key);
let decryptor = TripleDesDecryptor::new(key.as_slice().into(), &key.into());
let result = match padding {
super::Padding::NoPadding => decryptor
.decrypt_padded_vec_mut::<cipher::block_padding::NoPadding>(cipher_data.as_ref()),
super::Padding::ZeroPadding => decryptor
.decrypt_padded_vec_mut::<cipher::block_padding::ZeroPadding>(cipher_data.as_ref()),
super::Padding::Pkcs7Padding => {
decryptor.decrypt_padded_vec_mut::<cipher::block_padding::Pkcs7>(cipher_data.as_ref())
}
};
result.map_err(|_| super::DecryptFailedError {})
}
/// 快捷无填充加密函数
///
/// - `key` 密钥
/// - `plain_data` 明文数据
pub fn encrypt_no_padding<T: AsRef<[u8]>, D: AsRef<[u8]>>(key: T, plain_data: D) -> Vec<u8> {
encrypt(key, super::Padding::NoPadding, plain_data)
}
/// 快捷无填充解密函数
///
/// - `key` 密钥
/// - `cipher_data` 密文数据
pub fn decrypt_no_padding<T: AsRef<[u8]>, D: AsRef<[u8]>>(
key: T,
cipher_data: D,
) -> Result<Vec<u8>, super::DecryptFailedError> {
decrypt(key, super::Padding::NoPadding, cipher_data)
}
/// 快捷零填充加密函数
///
/// - `key` 密钥
/// - `plain_data` 明文数据
pub fn encrypt_zero_padding<T: AsRef<[u8]>, D: AsRef<[u8]>>(key: T, plain_data: D) -> Vec<u8> {
encrypt(key, super::Padding::ZeroPadding, plain_data)
}
/// 快捷零填充解密函数
///
/// - `key` 密钥
/// - `cipher_data` 密文数据
pub fn decrypt_zero_padding<T: AsRef<[u8]>, D: AsRef<[u8]>>(
key: T,
cipher_data: D,
) -> Result<Vec<u8>, super::DecryptFailedError> {
decrypt(key, super::Padding::ZeroPadding, cipher_data)
}
/// 快捷Pkcs7填充加密函数
///
/// - `key` 密钥
/// - `plain_data` 明文数据
pub fn encrypt_pkcs7_padding<T: AsRef<[u8]>, D: AsRef<[u8]>>(key: T, plain_data: D) -> Vec<u8> {
encrypt(key, super::Padding::Pkcs7Padding, plain_data)
}
/// 快捷Pkcs7填充解密函数
///
/// - `key` 密钥
/// - `cipher_data` 密文数据
pub fn decrypt_pkcs7_padding<T: AsRef<[u8]>, D: AsRef<[u8]>>(
key: T,
cipher_data: D,
) -> Result<Vec<u8>, super::DecryptFailedError> {
decrypt(key, super::Padding::Pkcs7Padding, cipher_data)
}