crypto.subtle无法解密,iv不是ArrayBuffer,加密数据未定义

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

我正在尝试加密文件并将其上传到云端,然后使用 Node.js v21.6.2 在本地解密。不幸的是,我在解密时遇到问题。我能够生成密钥并加密,但在 iv 上解密失败,据称它不是 ArrayBuffer,但应该是。有没有更好的方法来确保 iv 是缓冲区,以便我可以正确解密文件?我注意到加密的数据对象未定义,我不确定这是否是问题所在。有人对我做错了什么有任何想法吗?这是我收到的错误:

node:internal/webidl:181
  const err = new TypeError(message);
              ^

TypeError: Failed to execute 'decrypt' on 'SubtleCrypto': 3rd argument is not instance of ArrayBuffer, Buffer, TypedArray, or DataView.
    at codedTypeError (node:internal/webidl:181:15)
    at makeException (node:internal/webidl:190:10)
    at converters.BufferSource (node:internal/crypto/webidl:206:11)
    at SubtleCrypto.decrypt (node:internal/crypto/webcrypto:961:28)
    at decrypt (/Users/me/code/encryptiontest/aes/aes.js:31:43)
    at testEncryptionDecryption (/Users/me/code/encryptiontest/aes/aes.js:52:29) {
  code: 'ERR_INVALID_ARG_TYPE'
}

这是我的代码:

const { subtle } = globalThis.crypto;

async function generateAesKey(length = 256) {
    const key = await subtle.generateKey({
        name: 'AES-CBC',
        length,
    }, true, ['encrypt', 'decrypt']);

    return key;
}

async function aesEncrypt(plaintext) {
    const ec = new TextEncoder();
    const key = await generateAesKey();
    const iv = crypto.getRandomValues(new Uint8Array(16));

    const ciphertext = await crypto.subtle.encrypt({
        name: 'AES-CBC',
        iv,
    }, key, ec.encode(plaintext));

    return {
        key,
        iv,
        ciphertext,
    };
}

async function decrypt(ciphertext, key, iv) {
    const dec = new TextDecoder();
    const plaintext = await crypto.subtle.decrypt({
        name: 'AES-CBC',
        iv,
    }, key, ciphertext);

    return dec.decode(plaintext);
}

// takes Uint8Array and returns ArrayBuffer
function typedArrayToBuffer(array) {
    return array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset);
}


async function testEncryptionDecryption() {
    const data = "Hello, world!";
    console.log("ENCRYPTING DATA");
    const { key, iv, encrypted } = await aesEncrypt(data);
    console.log(iv);
    console.log("DECRYPTING DATA");
    console.log(typeof iv.buffer);
    const decrypted = await decrypt(encrypted, key, typedArrayToBuffer(iv));
    console.log("Original:", data);
    console.log("Decrypted:", decrypted);
}

testEncryptionDecryption();

我尝试在解密中使用 iv、iv.buffer 和 iv.buffer.slice,但收到一条错误消息,提示 iv 不是 ArrayBuffer、Buffer、TypedArray 或 DataView 的实例

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

你的问题不是IV(这是your

decrypt
函数的第三个参数),而是——正如错误消息所说——第三个参数
SubtleCrypto.decrypt
,它应该是密文,但实际上是
 undefined

这是因为你的线路

const { key, iv, encrypted } = await aesEncrypt(data);

aesEncrypt
返回一个包含
key iv ciphertext
但不包含
encrypted
的对象,因此这会将
key
iv
设置为返回对象中的成员(这是正确的),但不会将
encrypted
设置为任何内容,丢弃成员
ciphertext
的值。更改此代码和以下代码以提取并使用
ciphertext
并且它可以工作 - 并且只需简单的
iv

© www.soinside.com 2019 - 2024. All rights reserved.