Выборка зашифрованных данных буфера для использования в качестве ArrayBuffer для дешифрования на стороне клиента

#javascript #encryption #encryption-symmetric #arraybuffer

#javascript #шифрование #шифрование -симметричное #массивбуфер

Вопрос:

Я пытаюсь извлечь зашифрованные необработанные данные буфера (AES-256) из Arweave, перейти к функции дешифрования и использовать это для отображения изображения. Я пытаюсь извлечь и расшифровать ArrayBuffer на интерфейсе (в моем приложении React).

Сначала я шифрую данные буфера в NodeJS и сохраняю файл. Вот код для этого:

 /**********************
 **  Runs in NodeJS  **
 **********************/

const encrypt = (dataBuffer, key) => {
    // Create an initialization vector
    const iv = crypto.randomBytes(IV_LENGTH);
    // Create cipherKey
    const cipherKey = Buffer.from(key);
    // Create cipher
    const cipher = crypto.createCipheriv(ALGORITHM, cipherKey, iv);

    const encryptedBuffer = Buffer.concat([
        cipher.update(dataBuffer),
        cipher.final(),
    ]);
    const authTag = cipher.getAuthTag();
    let bufferLength = Buffer.alloc(1);
    bufferLength.writeUInt8(iv.length, 0);

    return Buffer.concat([bufferLength, iv, authTag, encryptedBuffer]);
};

const encryptedData = encrypt(data, key)

fs.writeFile("encrypted_data.enc", encryptedData, (err) => {
    if(err){
        return console.log(err)
    }
});

 

Затем я пытаюсь извлечь и расшифровать во внешнем интерфейсе. То, что у меня есть до сих пор, возвращает ArrayBuffer из ответа. Я пытаюсь передать этот ArrayBuffer функции decrypt . Вот код:

 /***********************
 **  Runs in React  **
 ***********************/
 import crypto from "crypto"

const getData = async (key) => {
  const result = await (await fetch('https://arweave.net/u_RwmA8gP0DIEeTBo3pOQTJ20LH2UEtT6LWjpLidOx0/encrypted_data.enc')).arrayBuffer()
  const decryptedBuffer = decrypt(result, key)
  console.log(decryptedBuffer)
}

//  Here is the decrypt function I am passing the ArrayBuffer to:
export const decrypt = (dataBuffer, key) => {
    // Create cipherKey
    const cipherKey = Buffer.from(key);
    // Get iv and its size
    const ivSize = dataBuffer.readUInt8(0);
    const iv = dataBuffer.slice(1, ivSize   1);
    // Get authTag - is default 16 bytes in AES-GCM
    const authTag = dataBuffer.slice(ivSize   1, ivSize   17);

    // Create decipher
    const decipher = crypto.createDecipheriv("aes-256-gcm", cipherKey, iv);
    decipher.setAuthTag(authTag);

    return Buffer.concat([
        decipher.update(dataBuffer.slice(ivSize   17)),
        decipher.final(),
    ]);
};
 

Когда я передаю данные ArrayBuffer в функцию decrypt, я получаю эту ошибку:

 Unhandled Rejection (TypeError): First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.
 

Комментарии:

1. Я рекомендую вам вырезать и вставлять точный текст любых ошибок, с которыми вы столкнулись, а не перефразировать.

2. И какой тип вещи вы передали вместо строки, буфера, ArrayBuffer, массива или объекта, подобного массиву ?

3. В чем проблема? Вы никогда не указываете ошибку. Я не уверен, почему этот вопрос набирает голоса.

4. @wahwahwah Ошибка цитируется дословно в первом буквальном блоке вопроса.

5. предоставьте весь свой код. Не опускайте вещи. определите, что выполняется в узле, а что в браузере.

Ответ №1:

Вы опускаете много деталей, которые помогли бы сообществу понять, как вы шифруете изображение, как вы его извлекаете и как вы его расшифровываете. Вот полный пример извлечения изображения, его шифрования, дешифрования и отображения в браузере. Это выполняется в Chrome v96 и Firefox v95.

 (async () => {
  const encryptionAlgoName = 'AES-GCM'
  const encryptionAlgo = {
      name: encryptionAlgoName,
      iv: window.crypto.getRandomValues(new Uint8Array(12)) // 96-bit
  }
  
  // create a 256-bit AES encryption key
  const encryptionKey = await crypto.subtle.importKey(
    'raw',
    new Uint32Array([1,2,3,4,5,6,7,8]),
    { name: encryptionAlgoName },
    true,
    ["encrypt", "decrypt"],
  )

  // fetch a JPEG image
  const imgBufferOrig = await (await fetch('https://fetch-progress.anthum.com/images/sunrise-baseline.jpg')).arrayBuffer()

  // encrypt the image
  const imgBufferEncrypted = await crypto.subtle.encrypt(
    encryptionAlgo,
    encryptionKey,
    imgBufferOrig
  )

  // decrypt recently-encrypted image
  const imgBufferDecrypted = await crypto.subtle.decrypt(
    encryptionAlgo, 
    encryptionKey,
    imgBufferEncrypted
  )

  // display unencrypted image
  const img = document.createElement('img')
  img.style.maxWidth = '100%'
  img.src = URL.createObjectURL(
    new Blob([ imgBufferDecrypted ])
  )
  document.body.append(img)    
})() 

Комментарии:

1. Спасибо за ваш ответ. Я искренне ценю вашу помощь. Мне жаль, что я не предоставил полную информацию, я пытался не делать ее слишком длинной, поэтому я допустил ошибку в сторону осторожности. Теперь я понимаю, что это был неправильный способ обратиться за помощью, поскольку это затрудняло помощь с моей конкретной ошибкой без контекста. Я запустил ваш код, и он работает точно так, как ожидалось. Я приложил к своему первоначальному вопросу некоторый код, показывающий, как я шифрую и сохраняю данные буфера из изображения. Я пишу в файловую систему моего сервера и извлекаю данные во внешнем интерфейсе для дешифрования.