# Tencent Hunyuan 3D API Reverse Engineering Document ## Project Overview This project reverse-engineers the frontend signing algorithm of Tencent Hunyuan 3D (https://3d.hunyuan.tencent.com/), enabling **pure Python HTTP calls** without a browser environment for features like image-to-3D generation and quota queries. --- ## Core Achievements ### 1. Signing Algorithm Cracked **Algorithm Location**: webpack Chunk 3057, Module 47436 **Signing Flow**: ``` 1. nonce generation: 16 iterations of Math.random(), selecting from 62-char set (A-Za-z0-9) 2. timestamp: Math.floor(Date.now() / 1000) (second-level timestamp) 3. key derivation: hardcoded byte array → XOR → circular left shift → permutation → truncation 4. signature: HMAC-SHA256(sorted query param string, derived key) → Hex ``` **Key Constants**: ```python C = bytes([122, 59, 92, 165, 30, 79, 166, 139, 142, 129, 139, 89, 219, 131, 101, 204]) D = bytes([122, 59, 92, 45, 30, 79, 106, 139, 156, 13, 46, 63, 74, 91, 108, 125]) U = [3, 5, 2, 7, 1, 4, 6, 2, 5, 3, 1, 4, 2, 6, 3, 5] # left shift bits M = [14, 11, 13, 9, 15, 10, 12, 8, 6, 3, 5, 1, 7, 2, 4, 0] # permutation table ``` **Derived Key**: `Hf6d6KFB3D` (10 characters) ### 2. Signing Scope (Important Finding) ⚠️ **The signature only covers URL query parameters, NOT the request body** Actual browser request: ``` POST /api/3d/creations/generations?timestamp=xxx&nonce=yyy&sign=zzz Body: {"sceneType":"playGround3D-2.0",...} ``` Signature computation: ```python # Only sign query params (timestamp + nonce) param_str = "nonce=yyy×tamp=xxx" sign = HMAC-SHA256(param_str, key="Hf6d6KFB3D") ``` ### 3. Image URL Format Must use Tencent's internal resource format: ``` https://3d.hunyuan.tencent.com/api/3d/resource/download?resourceId=<32-digit-hex> ``` You cannot directly use a COS URL; you must upload through the browser to obtain a resourceId. --- ## File Reference | File | Description | |------|-------------| | `hunyuan3dweb/sign.py` | Signing algorithm in pure Python | | `hunyuan3dweb/api.py` | Pure Python API client | | `hunyuan3dweb/browser/login.py` | Browser automation login tool | | `doc/api.md` | API endpoint documentation | --- ## Usage Flow ### 1. Login to Obtain Cookie ```bash hunyuan3dweb-login # Follow prompts to enter email and verification code # Login state is automatically saved to ~/.config/hunyuan3dweb/profile ``` ### 2. Pure Python 3D Generation ```python from hunyuan3dweb import Hunyuan3DAPI api = Hunyuan3DAPI() # Check quota quota = api.get_quota_info() # Generate 3D model result = api.generate_3d( image_url="https://3d.hunyuan.tencent.com/api/3d/resource/download?resourceId=...", scene_type="playGround3D-2.0", model_type="image2ModelV3.1" ) # Query status status = api.get_generation_status(result["creationsId"]) ``` --- ## API Endpoints | Feature | Method | Endpoint | Signature Scope | |---------|--------|----------|-----------------| | User info | GET | `/getuserinfo` | Query params | | Quota query | POST | `/quotainfo` | Query params | | Generate 3D | POST | `/creations/generations` | Query params | | Query status | GET | `/creations/detail` | Query params | --- ## Technical Details ### Signing Algorithm Implementation ```python def derive_key(c: bytes) -> str: """Derive signing key from hardcoded constants""" # 1. XOR with D t = bytearray(16) for i in range(16): t[i] = c[i] ^ D[i] # 2. Circular left shift o = bytearray(16) for i in range(16): n = U[i] val = t[i] o[i] = (val << n | val >> (8 - n)) & 0xFF # 3. Permutation n = bytearray(16) for i in range(16): n[i] = o[M[i]] # 4. Truncate (find first zero byte) try: r = n.index(0) except ValueError: r = 16 return n[:r].decode('utf-8') ``` ### Request Signing ```python def sign(params: dict) -> dict: result = dict(params) result["timestamp"] = int(time.time()) result["nonce"] = generate_nonce(16) # Sort and join (JSON format for lists/dicts) sorted_items = sort_params(result) param_str = join_params(sorted_items) # HMAC-SHA256 key = derive_key(C) signature = hmac.new( key.encode('utf-8'), param_str.encode('utf-8'), hashlib.sha256 ).hexdigest() result["sign"] = signature return result ``` --- ## Verification Results | Test Item | Browser Signature | Python Signature | Match | |-----------|-------------------|------------------|-------| | Fixed params | `2214e55a...` | `2214e55a...` | ✅ | | Quota query | Works | Works | ✅ | | Generate request | Works | Works | ✅ | | Status query | Works | Works | ✅ | --- ## Limitations and Notes 1. **Image Upload**: Still requires a browser environment to upload images and obtain resourceId (Tencent COS requires temporary signatures) 2. **Cookie Expiration**: Login sessions expire and need periodic re-login 3. **Quota Limit**: Each account has a generation quota limit (default 20/day) 4. **Rate Limiting**: Frequent calls may trigger anti-bot measures --- ## Dependencies ``` requests cloakbrowser (for login and upload) ``` --- ## Legal Notice This project is for educational and research purposes only. Use of this code is subject to Tencent Hunyuan 3D's Terms of Service. Do not use for commercial purposes or large-scale automated calling.