【问题标题】:WebCrypto API: DOMException: The provided data is too smallWebCrypto API:DOMException:提供的数据太小
【发布时间】:2021-05-15 05:44:38
【问题描述】:

我想在客户端(react.js)使用在后端加密的Web Crypto API 解密消息(node.js),但是我遇到了一个奇怪的问题并且没有任何知道出了什么问题(我还检查了this

node.js

function encrypt(message){
    const KEY = crypto.randomBytes(32)
    const IV = crypto.randomBytes(16)
    const ALGORITHM = 'aes-256-gcm';
    const cipher = crypto.createCipheriv(ALGORITHM, KEY, IV);
    let encrypted = cipher.update(message, 'utf8', 'hex');
    encrypted += cipher.final('hex');
    const tag = cipher.getAuthTag()
    let output = {
        encrypted,
        KEY: KEY.toString('hex'),
        IV: KEY.toString('hex'),
        TAG: tag.toString('hex'),
     }
    return output;
}

react.js

function decrypt() {
let KEY = hexStringToArrayBuffer(data.KEY);
let IV = hexStringToArrayBuffer(data.IV);
let encrypted = hexStringToArrayBuffer(data.encrypted);
let TAG = hexStringToArrayBuffer(data.TAG);

window.crypto.subtle.importKey('raw', KEY, 'AES-GCM', true, ['decrypt']).then((importedKey)=>{
  window.crypto.subtle.decrypt(
    {
      name: "AES-GCM",
      iv: IV,
    },
    importedKey,
    encrypted
  ).then((plaintext)=>{
    console.log('plainText: ', plaintext);
  })
})

function hexStringToArrayBuffer(hexString) {
  hexString = hexString.replace(/^0x/, '');
  if (hexString.length % 2 != 0) {
    console.log('WARNING: expecting an even number of characters in the hexString');
  }
  var bad = hexString.match(/[G-Z\s]/i);
  if (bad) {
    console.log('WARNING: found non-hex characters', bad);    
  }
  var pairs = hexString.match(/[\dA-F]{2}/gi);
  var integers = pairs.map(function(s) {
    return parseInt(s, 16);
  });
  var array = new Uint8Array(integers);
  return array.buffer;
} 

后端的加密没有任何错误,但是当想要在客户端解密消息时,浏览器(chrome)给出了这个错误:DOMException: The provided data is too small 当我运行firefox 浏览器上的程序给了我这个错误:DOMException: The operation failed for an operation-specific reason。太不清楚了!!

顺便问一下athentication tagAES-GCM中的用途是什么,需要在客户端解密吗?

【问题讨论】:

    标签: javascript encryption aes-gcm webcrypto-api node-crypto


    【解决方案1】:

    GCM 是经过身份验证的加密。解密需要认证标签。它用于检查密文的真实性,只有在确认解密时才会执行。
    由于标签未应用在您的 WebCrypto 代码中,因此身份验证和解密失败。

    WebCrypto 期望标签被附加到密文中:ciphertext |标签.

    以下代码中的数据是使用您的 NodeJS 代码创建的(请注意,NodeJS 代码中存在一个错误:密钥存储在 output 中,而不是 IV):

    decrypt();
     
    function decrypt() {
    
        let KEY = hexStringToArrayBuffer('684aa9b1bb4630f802c5c0dd1428403a2224c98126c1892bec0de00b65cc42ba');
        let IV = hexStringToArrayBuffer('775a446e052b185c05716dd1955343bb');
        let encryptedHex = 'a196a7426a9b1ee64c2258c1575702cf66999a9c42290a77ab2ff30037e5901243170fd19c0092eed4f1f8';
        let TAGHex = '14c03526e18502e4c963f6055ec1e9c0';
        let encrypted = hexStringToArrayBuffer(encryptedHex + TAGHex)
    
        window.crypto.subtle.importKey(
            'raw', 
            KEY,
            'AES-GCM', 
            true, 
            ['decrypt']
        ).then((importedKey)=> {
            window.crypto.subtle.decrypt(
                {
                    name: "AES-GCM",
                    iv: IV,
                },
                importedKey,
                encrypted
            ).then((plaintext)=>{
                console.log('plainText: ', ab2str(plaintext));
            });
        });
    }
    
    function hexStringToArrayBuffer(hexString) {
        hexString = hexString.replace(/^0x/, '');
        if (hexString.length % 2 != 0) {
            console.log('WARNING: expecting an even number of characters in the hexString');
        }
        var bad = hexString.match(/[G-Z\s]/i);
        if (bad) {
            console.log('WARNING: found non-hex characters', bad);    
        }
        var pairs = hexString.match(/[\dA-F]{2}/gi);
        var integers = pairs.map(function(s) {
            return parseInt(s, 16);
        });
        var array = new Uint8Array(integers);
        return array.buffer;
    } 
    
    function ab2str(buf) {
        return String.fromCharCode.apply(null, new Uint8Array(buf));
    }

    【讨论】:

      猜你喜欢
      • 2014-03-14
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 2011-06-29
      • 1970-01-01
      • 1970-01-01
      • 2019-11-22
      • 2015-02-28
      相关资源
      最近更新 更多