wechat_work_crypto 0.1.0

Pure Rust implementation of WeChat Work (企业微信) message encryption/decryption library
Documentation
#![allow(warnings)]

use wechat_work_crypto::WXBizMsgCrypt;

fn main() {
    // Configuration from WeChat
    const TOKEN: &str = "QDG6eK";
    // A valid 43-char base64 string that decodes to 32 bytes
    const ENCODING_AES_KEY: &str = "AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyA";
    const RECEIVE_ID: &str = "wx5823bf96d3bd56c7";

    // Initialize the crypto instance
    let crypt = WXBizMsgCrypt::new(TOKEN, ENCODING_AES_KEY, RECEIVE_ID)
        .expect("Failed to create WXBizMsgCrypt instance");

    println!("=== WeChat Crypto Library Demo ===\n");

    // Example 1: Verify URL (used during WeChat server verification)
    // First, we need to create valid encrypted data to verify
    println!("Example 1: Verify URL");
    let test_message = "hello from verify_url test";
    let timestamp = "1409659813";
    let nonce = "263014780";
    
    // Encrypt the test message to get valid echostr and signature
    match crypt.encrypt_msg(test_message, timestamp, nonce) {
        Ok(encrypted_xml) => {
            println!("  Generated encrypted message for verification...");
            
            // Extract the encrypted data and signature
            let encrypt_msg = wechat_work_crypto::WXBizMsgCrypt::get_xml_field(&encrypted_xml, "Encrypt").unwrap();
            let msg_signature = wechat_work_crypto::WXBizMsgCrypt::get_xml_field(&encrypted_xml, "MsgSignature").unwrap();
            
            // Now verify it using verify_url
            match crypt.verify_url(&msg_signature, timestamp, nonce, &encrypt_msg) {
                Ok(echo_result) => {
                    println!("✓ URL verification successful!");
                    println!("  Original message: {}", test_message);
                    println!("  Verified message: {}", echo_result);
                    if echo_result == test_message {
                        println!("  ✓ Verification matches original message!");
                    } else {
                        println!("  ✗ Verification doesn't match!");
                    }
                }
                Err(e) => {
                    println!("✗ URL verification failed: {} (error code: {})", e, e.error_code());
                }
            }
        }
        Err(e) => {
            println!("✗ Failed to generate test data: {} (error code: {})", e, e.error_code());
        }
    }

    println!();

    // Example 2: Encrypt a message
    println!("Example 2: Encrypt message");
    let reply_msg = r#"<xml>
<ToUserName><![CDATA[openID]]></ToUserName>
<FromUserName><![CDATA[gh_123456789]]></FromUserName>
<CreateTime>1409659813</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[Hello from Rust!]]></Content>
</xml>"#;
    let encrypt_timestamp = "1409659813";
    let encrypt_nonce = "263014780";

    match crypt.encrypt_msg(reply_msg, encrypt_timestamp, encrypt_nonce) {
        Ok(encrypted_xml) => {
            println!("✓ Message encrypted successfully!");
            println!("  Encrypted XML:\n{}", encrypted_xml);
            
            // Example 3: Decrypt the message back
            println!("\nExample 3: Decrypt message");
            let post_data = &encrypted_xml;
            
            // Extract signature from encrypted XML
            match wechat_work_crypto::WXBizMsgCrypt::get_xml_field(post_data, "MsgSignature") {
                Ok(signature) => {
                    match crypt.decrypt_msg(&signature, encrypt_timestamp, encrypt_nonce, post_data) {
                        Ok(decrypted_msg) => {
                            println!("✓ Message decrypted successfully!");
                            println!("  Decrypted message:\n{}", decrypted_msg);
                            
                            // Verify round-trip
                            if decrypted_msg == reply_msg {
                                println!("  ✓ Round-trip verification passed!");
                            } else {
                                println!("  ✗ Round-trip verification failed!");
                            }
                        }
                        Err(e) => {
                            println!("✗ Decryption failed: {} (error code: {})", e, e.error_code());
                        }
                    }
                }
                Err(e) => {
                    println!("✗ Failed to extract signature: {}", e);
                }
            }
        }
        Err(e) => {
            println!("✗ Encryption failed: {} (error code: {})", e, e.error_code());
        }
    }

    println!("\n=== Demo completed ===");
}