feat(crypto):增加螺旋自解密加密算法支持函数。
This commit is contained in:
parent
9a913b4bf4
commit
d9d24dbb54
|
@ -3,6 +3,7 @@ use thiserror::Error;
|
||||||
pub mod aes;
|
pub mod aes;
|
||||||
pub mod des;
|
pub mod des;
|
||||||
pub mod rsa;
|
pub mod rsa;
|
||||||
|
pub mod spiral;
|
||||||
pub mod tdes;
|
pub mod tdes;
|
||||||
|
|
||||||
pub enum Padding {
|
pub enum Padding {
|
||||||
|
|
59
src/encryption/spiral.rs
Normal file
59
src/encryption/spiral.rs
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
use aes::Aes256;
|
||||||
|
use cipher::{BlockDecryptMut, BlockEncryptMut, KeyIvInit};
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
type AesEncryptor = cbc::Encryptor<Aes256>;
|
||||||
|
type AesDecryptor = cbc::Decryptor<Aes256>;
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum SpiralCipherError {
|
||||||
|
#[error("Encrypted data corrupted")]
|
||||||
|
CorruptedCipherData,
|
||||||
|
#[error("Decrypt failed")]
|
||||||
|
DecryptFailed,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 生成一个随机密钥
|
||||||
|
fn gen_key(seed: &str) -> [u8; 32] {
|
||||||
|
let hash = crate::hash::sha512::hash_hex(seed);
|
||||||
|
hash.as_slice()[4..36].try_into().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 对给定的内容进行加密
|
||||||
|
///
|
||||||
|
/// - `data` 待加密的内容
|
||||||
|
pub fn encrypt(data: String) -> String {
|
||||||
|
let mut result = String::from("[");
|
||||||
|
let rand_key = crate::verifiy_code::random_verify_code(20);
|
||||||
|
let key = gen_key(&rand_key);
|
||||||
|
let iv: [u8; 16] = key[0..16].try_into().unwrap();
|
||||||
|
let encryptor = AesEncryptor::new(&key.into(), &iv.into());
|
||||||
|
let encrypted_data =
|
||||||
|
encryptor.encrypt_padded_vec_mut::<cipher::block_padding::Pkcs7>(data.as_bytes());
|
||||||
|
result.push_str(rand_key.as_ref());
|
||||||
|
result.push_str(crate::serialize::to_base64_str(&encrypted_data).as_ref());
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 对给定的内容进行解密
|
||||||
|
///
|
||||||
|
/// - `data` 待解密的内容
|
||||||
|
pub fn decrypt(data: String) -> Result<String, SpiralCipherError> {
|
||||||
|
if !data.starts_with("[") || data.len() <= 21 {
|
||||||
|
return Err(SpiralCipherError::CorruptedCipherData);
|
||||||
|
}
|
||||||
|
let data = data[1..].to_string();
|
||||||
|
let key_seed = data[0..20].to_string();
|
||||||
|
let key = gen_key(&key_seed);
|
||||||
|
let iv: [u8; 16] = key[0..16].try_into().unwrap();
|
||||||
|
let decryptor = AesDecryptor::new(&key.into(), &iv.into());
|
||||||
|
let encrypted_data = crate::serialize::from_base64_str(&data[20..])
|
||||||
|
.map_err(|_| SpiralCipherError::CorruptedCipherData)?;
|
||||||
|
let decrypted_data = decryptor
|
||||||
|
.decrypt_padded_vec_mut::<cipher::block_padding::Pkcs7>(encrypted_data.as_slice())
|
||||||
|
.map_err(|e| {
|
||||||
|
println!("error: {}", e);
|
||||||
|
SpiralCipherError::DecryptFailed
|
||||||
|
})?;
|
||||||
|
Ok(String::from_utf8_lossy(decrypted_data.as_slice()).to_string())
|
||||||
|
}
|
|
@ -6,6 +6,13 @@ pub mod md5 {
|
||||||
let result = hasher.finalize();
|
let result = hasher.finalize();
|
||||||
crate::serialize::to_hex(result.as_slice())
|
crate::serialize::to_hex(result.as_slice())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn hash_hex<T: AsRef<[u8]>>(input: T) -> Vec<u8> {
|
||||||
|
let mut hasher = md5::Md5::new();
|
||||||
|
hasher.update(input);
|
||||||
|
let result = hasher.finalize();
|
||||||
|
result.to_vec()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod sha1 {
|
pub mod sha1 {
|
||||||
|
@ -16,6 +23,13 @@ pub mod sha1 {
|
||||||
let result = hasher.finalize();
|
let result = hasher.finalize();
|
||||||
crate::serialize::to_hex(result.as_slice())
|
crate::serialize::to_hex(result.as_slice())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn hash_hex<T: AsRef<[u8]>>(input: T) -> Vec<u8> {
|
||||||
|
let mut hasher = sha1::Sha1::new();
|
||||||
|
hasher.update(input);
|
||||||
|
let result = hasher.finalize();
|
||||||
|
result.to_vec()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod sha512 {
|
pub mod sha512 {
|
||||||
|
@ -25,6 +39,13 @@ pub mod sha512 {
|
||||||
let result = hasher.finalize();
|
let result = hasher.finalize();
|
||||||
crate::serialize::to_hex(result.as_slice())
|
crate::serialize::to_hex(result.as_slice())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn hash_hex<T: AsRef<[u8]>>(input: T) -> Vec<u8> {
|
||||||
|
let mut hasher = hmac_sha512::Hash::new();
|
||||||
|
hasher.update(input);
|
||||||
|
let result = hasher.finalize();
|
||||||
|
result.to_vec()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod image_hash {
|
pub mod image_hash {
|
||||||
|
|
26
tests/spiral_cryption.rs
Normal file
26
tests/spiral_cryption.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#[cfg(test)]
|
||||||
|
mod spriral_test {
|
||||||
|
#[test]
|
||||||
|
fn encrypt_and_decrypt() {
|
||||||
|
let origin_text = "Hello, world!".to_string();
|
||||||
|
let encrypted_text = rs_toolbox::encryption::spiral::encrypt(origin_text.clone());
|
||||||
|
println!("encrypted_text: {}", encrypted_text);
|
||||||
|
let decrypted_text =
|
||||||
|
rs_toolbox::encryption::spiral::decrypt(encrypted_text).expect("decrypt failed");
|
||||||
|
assert_eq!(origin_text, decrypted_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn decrypt_foreign() {
|
||||||
|
let encrypted = "[13WOHv6CLGoIcqX5se6WvHM3pGNBH7wVJONahG7k0Q==".to_string();
|
||||||
|
let decrypted_text = match rs_toolbox::encryption::spiral::decrypt(encrypted) {
|
||||||
|
Ok(text) => text,
|
||||||
|
Err(e) => {
|
||||||
|
println!("error: {}", e);
|
||||||
|
panic!("decrypt failed");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
println!("decrypted_text: {}", decrypted_text);
|
||||||
|
assert_eq!("cxfh@83864830", decrypted_text);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user