NodeJS Apple Business Chat REST API,下载和解密大型交互消息

NodeJS Apple Business Chat REST API, Downloading and Decrypting Large interactive message

我正在阅读 apple business chat api 文档,我正在阅读“接收大型交互式数据有效负载”部分。最后一步是解密附件,然后发送到商务聊天 Api。

下载&数据步骤Documentation

--- 和解密指令DOCUMENTATION --

然后,使用密码库,使用 AES/CTR/NoPadding 算法和全零 16 字节初始化向量 (IV) 以及下载附件的附件字典中的键值来解密文件.

下面是我对这份文档的解释,因为它们几乎没有什么用处。


// The single-use, 256-bit AES key represented as a hex-encoded string.
const algorithm = 'aes-256-ctr';

// remove the 00 prefix from the hex-encoded string, 
// then decode the string into its original value. 
const key = Buffer.from(decryptKey.substr(2), 'hex');

// Use the decoded key value to decrypt the downloaded attachment file. 

// THE FULL IMPLEMENTATION

const iv = Buffer.alloc(16, 0);
const key = Buffer.from(decryptKey.substr(2), 'hex');
const decipher = crypto.createDecipheriv(algorithm, key, iv);
decipher.setAutoPadding(false)
let decrypted = decipher.update(data, '', 'hex');
decrypted += decipher.final('hex');
console.log("decrypted:", decrypted);

// Finally send to Apple Business Chat Api

    POST https://mspgw.push.apple.com/v1/decodePayload
accept: */*
accept-encoding: gzip, deflate
authorization: Bearer signed-web-token
source-id: business-id
bid: some-bid
 
{ attachment data }

//这里是传入数据的一部分

��F��˼����/��G����+��)��\M����x��tk��Y(����-��-G�ş$t����)

// 解密后

d3ffade249263d1252ee0dcfa6accd0beff31c607889ff0d31d893adde5063616a15591e181fb698350fb955f

当我将解密代码发送给 Apples 时,我不确定我是否正在正确解密 API

POST https://mspgw.push.apple.com/v1/decodePayload

总是代码响应400

我已就此问题联系 Apple 寻求帮助。我会在收到他们的回复后立即更新此文档。

下面是需要执行的步骤的图表。我卡在了最后两步。

这里是解决使用 apple business chat api 与 NodeJS 的解密问题的更新。主要问题是在发送给 Apple 进行解码之前将解密数据转换为缓冲区。

const decryptKeyFromInteractiveRef = "03f30ff3d3d03dc3".toUpperCase()

async function main(decryptKeyFromInteractiveRef) {

const url = await preDownloadUrl();

const data = await downloadPayload(url);

const decipheredData = await decipherInteractiveRef(data);

const decodedData = await appleDecode(decipheredData);
console.log("Finally your data", decodedData);

async function appleDecode(decipheredData) {

    var config = {
        method: 'post',
        url: 'https://mspgw.push.apple.com/v1/decodePayload',
        headers: {
            "Authorization": Authorization,
            "bid": "com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.icloud.apps.messages.business.extension",
            "source-id": BIZ_ID,
            "accept": "*/*",
            "accept-encoding": "gzip, deflate",
            'Content-Type': 'application/octet-stream'
        },
        data: decipheredData
    };

    const { data } = await axios(config);
    const path = Path.resolve(__dirname, 'images', 'data.json')
    fs.writeFileSync(path, JSON.stringify(data))
}


async function decipherInteractiveRef() {

    const iv = Buffer.alloc(16); // buffer alloc fills with zeros
    const key = Buffer.from(decryptKey.slice(2), 'hex',);
    const decipher = crypto.createDecipheriv("aes-256-ctr", key, iv);
    decipher.setAutoPadding(false); // No Padding
    let decrypted = decipher.update(data); // if input is a buffer dont choose a encoding

    return decrypted;
}


async function preDownloadUrl() {
    //Using the fields in the received interactiveDataRef key, 
    // retrieve the URL to the payload by calling the /preDownload endpoint.

    //interactiveDataRef key
    const signatureHex = "81101cc048b6b588c895f01c12715421f9d0a25329".toUpperCase()
    const signature = Buffer.from(signatureHex, 'hex').toString('base64')

    var configInteractiveRef = {
        method: 'get',
        url: 'https://mspgw.push.apple.com/v1/preDownload',
        headers: {
            'Authorization': Authorization,
            'source-id': BIZ_ID,
            'MMCS-Url': 'https://p56-content.icloud.com/MZ02db38070edccb2ce8c972efdcdd25437439745cad6f15473bb7880d436377702752e134be8bd3b4d695567a5d574142.C01USN00',
            'MMCS-Signature': signature,
            'MMCS-Owner': 'MZ02db38070edccb2ce8c972efdcdd25437439745cad6f15473bb7880d436377702752e134be8bd3b4d695567a5d574142.C01USN00'
        }
    };

    const response = await axios(configInteractiveRef)
    return response.data["download-url"];
}

// download big payload from apple
async function downloadPayload(url) {
    const { data } = await axios.get(url, { responseType: 'arraybuffer' });
    return data
}}