# wechat_work_crypto
[](https://crates.io/crates/wechat_work_crypto)
[](https://gitcode.net/dnrops/wechat_work_crypto)
[](https://gitcode.net/dnrops/wechat_work_crypto/-/raw/master/LICENSE)
## 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`:
```toml
[dependencies]
wechat_work_crypto = "0.1.0"
```
## Usage
### Basic Setup
```rust
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:
```rust
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:
```rust
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:
```rust
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:
| 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:
1. **Encryption Format**: `random(16B) + msg_len(4B) + msg + corpId`
2. **Random String**: 16 random printable ASCII characters
3. **Message Length**: 4 bytes in network byte order (big-endian)
4. **AES-256-CBC**: With PKCS7 padding
5. **IV**: Uses the first 16 bytes of the AES key
6. **Signature**: SHA1 hash of sorted `token + timestamp + nonce + encrypted_msg`
## Testing
Run the test suite:
```bash
cargo test
```
Run the example:
```bash
cargo run
```
## API Reference
### WXBizMsgCrypt
Main struct for WeChat Work crypto operations.
#### Methods
- `new(token, encoding_aes_key, receive_id)` - Create a new instance
- `verify_url(msg_signature, timestamp, nonce, echo_str)` - Verify URL
- `decrypt_msg(msg_signature, timestamp, nonce, post_data)` - Decrypt message
- `encrypt_msg(reply_msg, timestamp, nonce)` - Encrypt message
- `get_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 encryption
- `cbc` - CBC mode of operation
- `base64` - Base64 encoding/decoding
- `sha1` - SHA1 hashing
- `hex` - Hex encoding
- `rand` - Random number generation
- `regex` - XML parsing
- `thiserror` - 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 `unsafe` code is introduced