nodejs解密错误:不支持的状态或无法验证数据

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

我遇到以下错误:

错误:不支持的状态或无法验证数据 在 Decipheriv.final

这是我的加密代码(在reactjs中):

async function encryptJsonData(jsonData, secretKey) {
    const encoder = new TextEncoder();
    const data = encoder.encode(JSON.stringify(jsonData));
    const key = await window.crypto.subtle.importKey(
        "raw",
        encoder.encode(secretKey.slice(0, 32)),
        { name: "AES-GCM", length: 256 },
        false,
        ["encrypt"]
    );
    const iv = window.crypto.getRandomValues(new Uint8Array(12));
    const encrypted = await window.crypto.subtle.encrypt(
        { name: "AES-GCM", iv },
        key,
        data
    );
    return {
        iv: Array.from(iv),
        data: Array.from(new Uint8Array(encrypted)),
    };
}

在nodejs中解密的代码:

const crypto = require('crypto');

const decryptJsonData = async (encryptedData, secretKey) => {
    const { iv, data } = encryptedData;
    const key = crypto.createSecretKey(Buffer.from(secretKey), 'utf-8');
    
    const decipher = crypto.createDecipheriv('aes-256-gcm', key, Buffer.from(iv));

    let decrypted = decipher.update(Buffer.from(data));
    decrypted = Buffer.concat([decrypted, decipher.final()]);

    return JSON.parse(decrypted.toString());
}

module.exports = decryptJsonData

我尝试了多种方法来解决该错误但失败了,我使用了 auth_tags 也没有任何效果。请帮忙!!!

我尝试过使用auth_tags,还有更多的东西,但没有任何效果。

node.js encryption aes cryptojs node-crypto
1个回答
0
投票

WebCrypto API 隐式连接密文和身份验证标记(密文 | 16 字节标记),而 NodeJS 的加密模块单独处理两者。

因此,解密时必须首先将密文和标签分开。必须使用

setAuthTag()
明确设置标签。这必须发生在创建
decipher
实例和
final()
调用之间:

var dataBuf = Buffer.from(data);                                                 // separate ciphertetxt and tag
var ciphertext = dataBuf.subarray(0, -16);
var tag = dataBuf.subarray(-16);
...
const decipher = crypto.createDecipheriv('aes-256-gcm', key, Buffer.from(iv));
decipher.setAuthTag(tag);                                                        // pass tag
let decrypted = decipher.update(ciphertext);                                     // pass ciphertext
decrypted = Buffer.concat([decrypted, decipher.final()]);
© www.soinside.com 2019 - 2024. All rights reserved.