如何从WhatsApp API Webhook的JSON中解密获取可转录音频文件
解密WhatsApp Webhook返回的加密音频文件(.enc转.oga/mpga)
问题描述
通过第三方API对接WhatsApp实例,监听Webhook获取音频用于AI转录时,Webhook返回的JSON中audioMessage.url指向的是加密的.enc文件,无法直接使用,需要解密为.oga或.mpga格式。示例Webhook响应如下:
{"instance_id": "670F8EB71BCC8","data": {"event": "messages.upsert","data": {"messages": [{"key": {"remoteJid": "923411363215@s.whatsapp.net","fromMe": false,"id": "3EB0C786C5ECC3DB8EF55E"},"messageTimestamp": 1730370494,"pushName": "Gulshan Fatima","broadcast": false,"message": {"audioMessage": {"url": "https://mmg.whatsapp.net/v/t62.7117-24/23769379_1887584434985641_7294817018279328005_n.enc?ccb=11-4&oh=01_Q5AaIE6U4-DRcQ07AFaPQvh-xq7p3-hj5NfmgySTm-o6zykg&oe=674A9F4D&_nc_sid=5e03e0&mms3=true","mimetype": "audio/ogg; codecs=opus","fileSha256": "q1J4mSqx0vE8oNQxqSdiLiT4UqeJoDm9Pcx/5o5goNg=","fileLength": "17290","seconds": 7,"ptt": false,"mediaKey": "HkWlGGL7T4A+pN5S7Dc1M/aIoKZUM+plEsY+UbFoBE0=","fileEncSha256": "faJu9zOAcGnB+wCvqwk/Rs/0AOkITRiPCOAw2xY1TQ8=","directPath": "/v/t62.7117-24/23769379_1887584434985641_7294817018279328005_n.enc?ccb=11-4&oh=01_Q5AaIE6U4-DRcQ07AFaPQvh-xq7p3-hj5NfmgySTm-o6zykg&oe=674A9F4D&_nc_sid=5e03e0","mediaKeyTimestamp": "1730365220","contextInfo": {"ephemeralSettingTimestamp": "1730363593","disappearingMode": {"initiator": "CHANGED_IN_CHAT"}},"waveform": "AAAAASsnGwwAAAAFL0AyLSk6KwQAJQAAAkM5JzAxHUk4LwA7Ezc2ODMBOzEFOwxERAYqPzoVADM8NT8qJDRGEQ==","viewOnce": false},"messageContextInfo": {"deviceListMetadata": {"senderKeyHash": "UGQQlAh12HnI7Q==","senderTimestamp": "1730363426","recipientKeyHash": "M3OjUavSOixxMw==","recipientTimestamp": "1729072828"},"deviceListMetadataVersion": 2,"messageSecret": "0PAvJrpZ0v+OEKdfOoJuOp9K7rf5+VMhqFs/mnMwxAg="}}],"type": "notify"}}}
解密方案
WhatsApp媒体文件采用AES-256-GCM加密,解密核心依赖JSON中的mediaKey字段,具体步骤如下:
1. 解码MediaKey
将Base64编码的mediaKey转换为二进制数据。
2. 派生解密密钥与IV
使用固定盐值WhatsApp Audio Keys,通过HMAC-SHA256从mediaKey中派生:
- 密钥:取HMAC结果的前32字节
- IV:取HMAC结果的最后12字节
3. 处理加密文件
从audioMessage.url下载.enc文件,文件结构为:
- 前16字节:GCM认证标签(用于验证解密完整性)
- 剩余内容:加密的音频数据
4. AES-GCM解密
用派生的密钥和IV对加密数据解密,同时验证认证标签。
5. 保存为可用格式
解密后的原始数据对应mimetype指定的格式(示例为audio/ogg; codecs=opus),直接保存为.oga即可用于AI转录。
Python代码实现
import base64 import hmac import hashlib from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend import requests def decrypt_whatsapp_audio(media_key_b64, encrypted_file_path, output_file_path): # 解码Base64格式的mediaKey media_key = base64.b64decode(media_key_b64) # 派生密钥和IV salt = b"WhatsApp Audio Keys" hmac_result = hmac.new(salt, media_key, hashlib.sha256).digest() aes_key = hmac_result[:32] aes_iv = hmac_result[-12:] # 读取加密文件 with open(encrypted_file_path, 'rb') as f: encrypted_data = f.read() # 分离认证标签和加密内容 tag = encrypted_data[:16] ciphertext = encrypted_data[16:] # AES-GCM解密 cipher = Cipher(algorithms.AES(aes_key), modes.GCM(aes_iv, tag), backend=default_backend()) decryptor = cipher.decryptor() plain_audio = decryptor.update(ciphertext) + decryptor.finalize() # 保存解密后的音频文件 with open(output_file_path, 'wb') as f: f.write(plain_audio) # 示例使用 if __name__ == "__main__": # 从Webhook响应中提取的mediaKey和音频URL media_key = "HkWlGGL7T4A+pN5S7Dc1M/aIoKZUM+plEsY+UbFoBE0=" audio_url = "https://mmg.whatsapp.net/v/t62.7117-24/23769379_1887584434985641_7294817018279328005_n.enc?ccb=11-4&oh=01_Q5AaIE6U4-DRcQ07AFaPQvh-xq7p3-hj5NfmgySTm-o6zykg&oe=674A9F4D&_nc_sid=5e03e0&mms3=true" # 下载加密文件 encrypted_file = "encrypted_audio.enc" response = requests.get(audio_url) with open(encrypted_file, 'wb') as f: f.write(response.content) # 解密并保存为OGG文件 output_file = "decrypted_audio.oga" decrypt_whatsapp_audio(media_key, encrypted_file, output_file)
注意事项
mediaKey是每个媒体文件的唯一密钥,由第三方API提供,确保其有效性和正确性。- 解密后的格式由
audioMessage.mimetype决定,若为audio/mpeg则保存为.mp3。 - 若认证标签验证失败,需检查加密文件的完整性或
mediaKey是否匹配。
内容的提问来源于stack exchange,提问作者Imran Rashid
相关产品推荐
相关产品推荐

