WhatsApp Flows解密报错:error:02000079:rsa routines::oaep decoding error
解决WhatsApp Flows API解密时的ERR_OSSL_RSA_OAEP_DECODING_ERROR错误
问题场景
集成WhatsApp Flows API时,按照官方示例实现解密逻辑,在调用crypto.privateDecrypt解密AES密钥时触发以下错误:
{ "code": "ERR_OSSL_RSA_OAEP_DECODING_ERROR", "library": "rsa routines", "reason": "oaep decoding error", "message": "error:02000079:rsa routines::oaep decoding error", "stack": "Error: error:02000079:rsa routines::oaep decoding error\n at Object.privateDecrypt (node:internal/crypto/cipher:79:12)\n at decryptRequest" }
解决方案
1. 确保私钥格式符合要求
WhatsApp Flows要求使用PKCS#8格式的RSA私钥,若当前私钥是PKCS#1格式(头为-----BEGIN RSA PRIVATE KEY-----),需转换为PKCS#8:
# 无密码私钥转换 openssl pkcs8 -topk8 -inform PEM -in private_key.pem -out private_key_pkcs8.pem -nocrypt # 带密码私钥转换(执行后输入密码) openssl pkcs8 -topk8 -inform PEM -in private_key.pem -out private_key_pkcs8.pem
转换完成后,更新代码中的PRIVATE_KEY_PATH指向新的PKCS#8格式私钥文件。
2. 修正RSA解密参数
WhatsApp Flows的RSA-OAEP解密要求MGF1哈希算法为SHA-256,但Node.js crypto.privateDecrypt默认使用SHA-1,需显式指定mgf1Hash参数:
修改decryptRequest函数中的privateDecrypt配置:
const decryptedAesKey = crypto.privateDecrypt( { key: crypto.createPrivateKey( { key: privatePem, passphrase: passphrase, } ), padding: crypto.constants.RSA_PKCS1_OAEP_PADDING, oaepHash: "sha256", mgf1Hash: "sha256" // 新增此参数,指定MGF1哈希算法 }, Buffer.from(encrypted_aes_key, "base64"), );
3. 验证密钥与请求数据完整性
- 确认私钥密码(
PRIVATE_KEY_PASSPHRASE)完全正确,注意大小写、特殊字符的输入 - 打印
body.encrypted_aes_key确认其为完整的base64字符串,未被截断或转义 - 确保
express.json()中间件未修改请求体结构,可临时关闭中间件用express.raw()接收原始请求验证
4. 升级Node.js版本
旧版本Node.js(如14.x及以下)的crypto模块对RSA-OAEP参数支持存在兼容性问题,建议升级到Node.js 16.x及以上版本。
修改后的完整decryptRequest函数
const decryptRequest = async (body, privatePem, passphrase) => { try { const { encrypted_aes_key, encrypted_flow_data, initial_vector } = body; // Decrypt the AES key created by the client const decryptedAesKey = crypto.privateDecrypt( { key: crypto.createPrivateKey( { key: privatePem, passphrase: passphrase, } ), padding: crypto.constants.RSA_PKCS1_OAEP_PADDING, oaepHash: "sha256", mgf1Hash: "sha256" // 新增MGF1哈希配置 }, Buffer.from(encrypted_aes_key, "base64"), ); // Decrypt the Flow data const flowDataBuffer = Buffer.from(encrypted_flow_data, "base64"); const initialVectorBuffer = Buffer.from(initial_vector, "base64"); const TAG_LENGTH = 16; const encrypted_flow_data_body = flowDataBuffer.subarray(0, -TAG_LENGTH); const encrypted_flow_data_tag = flowDataBuffer.subarray(-TAG_LENGTH); const decipher = crypto.createDecipheriv( "aes-128-gcm", decryptedAesKey, initialVectorBuffer, ); decipher.setAuthTag(encrypted_flow_data_tag); const decryptedJSONString = Buffer.concat([ decipher.update(encrypted_flow_data_body), decipher.final(), ]).toString("utf-8"); return { decryptedBody: JSON.parse(decryptedJSONString), aesKeyBuffer: decryptedAesKey, initialVectorBuffer, }; } catch (e) { console.log('Error decoding:', e) } };
内容的提问来源于stack exchange,提问作者Shanthi B
相关产品推荐
相关产品推荐

