wechat-api-rs 0.1.0

A Rust SDK for WeChat Official Account and Mini Program APIs
Documentation
//! WeChat cryptographic utilities

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>;

/// Verify WeChat signature
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
}

/// Generate MD5 hash
pub fn md5_hash(input: &str) -> String {
    format!("{:x}", md5::compute(input))
}

/// Base64 encode
pub fn base64_encode(input: &[u8]) -> String {
    use base64::Engine;
    base64::engine::general_purpose::STANDARD.encode(input)
}

/// Base64 decode
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()))
}

/// Generate signature for API calls
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()
}