在WhatsApp Flow执行data_exchange时遇payload解密失败求助
WhatsApp Flow Data Exchange 解密错误排查求助
执行WhatsApp Flow的data_exchange操作时触发错误,使用的是Facebook官方data_exchange示例,收到错误提示:
We failed to decrypt your payload. Please check your encryption/decryption logic.
自身编写的解密代码能正常运行,以下是相关代码,请求协助排查问题:
解密代码
def decrypt_request(self,encrypted_flow_data_b64, encrypted_aes_key_b64, initial_vector_b64): flow_data = b64decode(encrypted_flow_data_b64) iv = b64decode(initial_vector_b64) # 解密AES密钥 encrypted_aes_key = b64decode(encrypted_aes_key_b64) PRIVATE_KEY = request.env['res.company'].search([],limit=1) encoded_data = b64decode(PRIVATE_KEY.private_key_attachment).decode('utf-8').encode('utf-8') private_key = load_pem_private_key( encoded_data, password=None) aes_key = private_key.decrypt(encrypted_aes_key, OAEP( mgf=MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None)) # 解密Flow数据 encrypted_flow_data_body = flow_data[:-16] encrypted_flow_data_tag = flow_data[-16:] decryptor = Cipher(algorithms.AES(aes_key), modes.GCM(iv, encrypted_flow_data_tag)).decryptor() decrypted_data_bytes = decryptor.update( encrypted_flow_data_body) + decryptor.finalize() decrypted_data = json.loads(decrypted_data_bytes.decode("utf-8")) return decrypted_data, aes_key, iv
加密代码
def encrypt_response(self,response, aes_key, iv): # 翻转初始化向量 flipped_iv = bytearray(b ^ 0xFF for b in iv) # 加密响应数据 encryptor = Cipher( algorithms.AES(aes_key), modes.GCM(flipped_iv[:12]), backend=default_backend() ).encryptor() # 加密并完成 response_bytes = json.dumps(response).encode("utf-8") ciphertext = encryptor.update(response_bytes) + encryptor.finalize() # 拼接密文和标签 encrypted_payload = ciphertext + encryptor.tag # Base64编码 encoded_payload = b64encode(encrypted_payload).decode("utf-8") return encoded_payload
主方法代码
def whatsapp_data_exchange_flow(self,**kw): data = json.loads(request.httprequest.data) # 读取请求字段 encrypted_flow_data_b64 = data['encrypted_flow_data'] encrypted_aes_key_b64 = data['encrypted_aes_key'] initial_vector_b64 = data['initial_vector'] decrypted_data, aes_key, iv = self.decrypt_request( encrypted_flow_data_b64, encrypted_aes_key_b64, initial_vector_b64) print(decrypted_data) # 返回下一个页面及数据给客户端 response = { "version": "3.0", "screen": "BOOKING_INFO" } encrpted_response = self.encrypt_response(response, aes_key, iv) headers = werkzeug.datastructures.Headers(None) headers['Content-Type'] = 'text/plain' response = request.make_response(final_response,headers=headers.to_wsgi_list(),status=200) return response
可能的排查方向
- 变量名错误:主方法中
final_response未定义,实际应使用加密后的encrpted_response,此错误会导致返回无效内容,触发解密失败 - IV处理验证:确认原IV长度是否为12字节(GCM标准长度),加密时截取
flipped_iv[:12]若原IV长度不足会导致IV异常 - 响应格式检查:确保返回的是纯Base64字符串,无额外空格、换行或其他字符
- 密钥解密参数:验证OAEP填充的哈希算法、MGF函数是否与Facebook官方要求完全一致
- 响应头确认:虽然官方文档标注返回
text/plain,但可尝试切换为application/json测试是否兼容
内容的提问来源于stack exchange,提问作者Mayur Nagar
相关产品推荐
相关产品推荐

