WhatsApp Flows 解密错误 - 错误:02000079:rsa 例程::oaep 解码错误

问题描述 投票:0回答:1

我利用 WhatsApp Flows API 将流集成到我们的应用程序中。发布流程时,我需要使用以下结构对其进行解密:

{
    encrypted_flow_data: "<ENCRYPTED FLOW DATA>",
    encrypted_aes_key: "<ENCRYPTED_AES_KEY>",
    initial_vector: "<INITIAL VECTOR>"
 }

参考此文档(https://developers.facebook.com/docs/whatsapp/flows/guides/implementingyourflowendpoint#nodejs-express-example)来解密密钥。

但是,我遇到以下错误:

{
"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"

}

供参考,以下是相关代码片段:

const express = require("express");
const crypto = require("crypto");
const fs = require('fs');
const util = require('util');
const { promisify } = require('util');
const readFile = promisify(fs.readFile);

require("dotenv").config();

const PORT = 3000;
const app = express();
app.use(express.json());

app.post("/data", async ({ body }, res) => {
    const PRIVATE_KEY_PATH = 'path/to/your/private_key.pem'; 
    const PRIVATE_KEY_PASSPHRASE = 'your_private_key_passphrase';

    const PRIVATE_KEY = await readFile(PRIVATE_KEY_PATH, 'utf-8');

    const { decryptedBody, aesKeyBuffer, initialVectorBuffer } = decryptRequest(
        body,
        PRIVATE_KEY,
        PRIVATE_KEY_PASSPHRASE,
    );

    const { screen, data, version, action } = decryptedBody;
    // Return the next screen & data to the client
    const screenData = {
        version,
        screen: "SCREEN_NAME",
        data: {
            some_key: "some_value",
        },
    };

    // Return the response as plaintext
    res.send(encryptResponse(screenData, aesKeyBuffer, initialVectorBuffer));
});

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",
            },
            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)
    }
};

const encryptResponse = (
    response,
    aesKeyBuffer,
    initialVectorBuffer,
) => {
    // Flip the initialization vector
    const flipped_iv = [];
    for (const pair of initialVectorBuffer.entries()) {
        flipped_iv.push(~pair[1]);
    }
    // Encrypt the response data
    const cipher = crypto.createCipheriv(
        "aes-128-gcm",
        aesKeyBuffer,
        Buffer.from(flipped_iv),
    );
    return Buffer.concat([
        cipher.update(JSON.stringify(response), "utf-8"),
        cipher.final(),
        cipher.getAuthTag(),
    ]).toString("base64");
};

app.listen(PORT, () => {
    console.log(`App is listening on port ${PORT}!`);
});

您能帮我解决这个问题吗?我提前感谢您的帮助。谢谢你。

node.js cryptography cryptojs whatsapp-flows
1个回答
0
投票

解密代码对我来说似乎很好。问题可能出在私钥上。

  1. 您可以验证私钥和公钥是否匹配吗?您可以记录私钥以确认其正确性。
  2. 您可以使用公钥加密任意有效负载并验证您可以使用当前代码解密它吗?
© www.soinside.com 2019 - 2024. All rights reserved.