use thiserror::Error;
use sha1::{Sha1, Digest};
#[derive(Error, Debug)]
pub enum CryptoError {
#[error("Invalid signature")]
InvalidSignature,
#[error("Decryption failed: {0}")]
DecryptionFailed(String),
#[error("Encryption failed: {0}")]
EncryptionFailed(String),
}
pub type Result<T> = std::result::Result<T, CryptoError>;
pub fn verify_signature(token: &str, timestamp: &str, nonce: &str, signature: &str) -> bool {
let mut params = vec![token, timestamp, nonce];
params.sort();
let content = params.join("");
let mut hasher = Sha1::new();
hasher.update(content.as_bytes());
let hash = format!("{:x}", hasher.finalize());
hash == signature
}
pub fn md5_hash(input: &str) -> String {
format!("{:x}", md5::compute(input))
}
pub fn base64_encode(input: &[u8]) -> String {
use base64::Engine;
base64::engine::general_purpose::STANDARD.encode(input)
}
pub fn base64_decode(input: &str) -> Result<Vec<u8>> {
use base64::Engine;
base64::engine::general_purpose::STANDARD.decode(input)
.map_err(|e| CryptoError::DecryptionFailed(e.to_string()))
}
pub fn generate_signature(params: &[(&str, &str)]) -> String {
let mut params: Vec<_> = params.iter().collect();
params.sort_by(|a, b| a.0.cmp(b.0));
let content: String = params
.iter()
.map(|(k, v)| format!("{}={}", k, v))
.collect::<Vec<_>>()
.join("&");
md5_hash(&content).to_uppercase()
}