1 unstable release
| 0.1.0 | Jan 23, 2026 |
|---|
#1916 in Cryptography
28KB
393 lines
wechat_work_crypto
WeChat Work (WeCom) Crypto Library - Pure Rust Implementation
A pure Rust implementation of the WeChat Work (企业微信) message encryption/decryption library, ported from the official C++ SDK.
Features
- ✅ AES-256-CBC encryption/decryption
- ✅ Base64 encoding/decoding
- ✅ SHA1 signature computation
- ✅ XML parsing and generation
- ✅ Message encryption and decryption
- ✅ URL verification for WeChat server callback
- ✅ Full error handling with proper error codes
- ✅ Zero unsafe code
- ✅ Idiomatic Rust API
Installation
Add this to your Cargo.toml:
[dependencies]
wechat_work_crypto = "0.1.0"
Usage
Basic Setup
use wechat_work_crypto::WXBizMsgCrypt;
// Configuration from WeChat Work
let token = "your_token_here";
let encoding_aes_key = "jWmYm7qr5nMoAUwZRjGtBxmz3PL1k2yftF4vsTlMqPS";
let receive_id = "your_corpid_here";
// Initialize the crypto instance
let crypt = WXBizMsgCrypt::new(token, encoding_aes_key, receive_id)?;
Verify URL (Server Verification)
When WeChat Work verifies your server:
let msg_signature = "5c45ff5e21c57e6ad56bac8c868eb9068928468d";
let timestamp = "1409659813";
let nonce = "263014780";
let echo_str = "P9nAzCzyDtyTWESHep1vC5X9xho/qYX3Zpb4yKa9SKld1DsH3Iyt3tP3zNdV+SNh2FvLm0Yc1HlON16aRqv3+A==";
let echo_result = crypt.verify_url(msg_signature, timestamp, nonce, echo_str)?;
println!("Verified: {}", echo_result);
Decrypt Messages
Decrypt messages received from WeChat Work:
let msg_signature = "signature_from_url";
let timestamp = "1409659813";
let nonce = "263014780";
let post_data = r#"<xml>
<Encrypt><![CDATA[encrypted_content_here]]></Encrypt>
<MsgSignature><![CDATA[signature]]></MsgSignature>
<TimeStamp>1409659813</TimeStamp>
<Nonce><![CDATA[263014780]]></Nonce>
</xml>"#;
let decrypted_msg = crypt.decrypt_msg(msg_signature, timestamp, nonce, post_data)?;
println!("Decrypted: {}", decrypted_msg);
Encrypt Messages
Encrypt messages to send back to WeChat Work:
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 timestamp = "1409659813";
let nonce = "263014780";
let encrypted_xml = crypt.encrypt_msg(reply_msg, timestamp, nonce)?;
println!("Encrypted: {}", encrypted_xml);
Error Codes
The library returns proper error codes matching the official C++ SDK:
| Error Code | Error Name | Description |
|---|---|---|
| 0 | OK | Success |
| -40001 | ValidateSignatureError | Signature validation failed |
| -40002 | ParseXmlError | XML parsing error |
| -40003 | ComputeSignatureError | Signature computation error |
| -40004 | IllegalAesKey | Invalid AES key |
| -40005 | ValidateCorpidError | CorpId validation failed |
| -40006 | EncryptAESError | AES encryption error |
| -40007 | DecryptAESError | AES decryption error |
| -40008 | IllegalBuffer | Invalid buffer |
| -40009 | EncodeBase64Error | Base64 encoding error |
| -40010 | DecodeBase64Error | Base64 decoding error |
| -40011 | GenReturnXmlError | XML generation error |
Encryption Details
The library implements the WeChat Work encryption protocol:
- Encryption Format:
random(16B) + msg_len(4B) + msg + corpId - Random String: 16 random printable ASCII characters
- Message Length: 4 bytes in network byte order (big-endian)
- AES-256-CBC: With PKCS7 padding
- IV: Uses the first 16 bytes of the AES key
- Signature: SHA1 hash of sorted
token + timestamp + nonce + encrypted_msg
Testing
Run the test suite:
cargo test
Run the example:
cargo run
API Reference
WXBizMsgCrypt
Main struct for WeChat Work crypto operations.
Methods
new(token, encoding_aes_key, receive_id)- Create a new instanceverify_url(msg_signature, timestamp, nonce, echo_str)- Verify URLdecrypt_msg(msg_signature, timestamp, nonce, post_data)- Decrypt messageencrypt_msg(reply_msg, timestamp, nonce)- Encrypt messageget_xml_field(xml_data, field_name)- Extract field from XML (static method)
WXBizMsgCryptError
Error enum with comprehensive error handling.
Methods
error_code()- Get the numeric error code
Dependencies
aes- AES encryptioncbc- CBC mode of operationbase64- Base64 encoding/decodingsha1- SHA1 hashinghex- Hex encodingrand- Random number generationregex- XML parsingthiserror- Error handling
License
This implementation follows the same licensing as the original WeChat Work SDK.
Contributing
Contributions are welcome! Please ensure:
- All tests pass
- Code follows Rust best practices
- Documentation is updated
- No
unsafecode is introduced
Dependencies
~5–6.5MB
~122K SLoC