Chrome扩展中Drive API与CryptoJS加密回写报错及类型验证问题
解决CryptoJS加密错误及Drive API上传问题
首先,你遇到的RangeError: Invalid array length是因为调用CryptoJS.AES.encrypt的方式错误。解密时我们需要传入{ ciphertext: respWordArray }是因为要告诉CryptoJS这是已有的密文,但加密时不需要这么做——直接传入要加密的明文(你的newWordArray)即可。
修正后的加密代码
把你的加密部分改成这样:
let newtext = JSON.stringify(respJson); let newWordArray = CryptoJS.enc.Utf8.parse(newtext); // 注意这里直接传入newWordArray,不是{ciphertext: ...} let ecWordArray = CryptoJS.AES.encrypt( newWordArray, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 } );
这个错误是因为你误用了解密时的参数格式来加密,导致CryptoJS内部处理数组时出现长度异常。
问题1:验证newWordArray和dcWordArray是否为WordArray类型
你可以通过两种方式验证:
- 使用
instanceof判断:console.log(newWordArray instanceof CryptoJS.lib.WordArray); // 应该返回true console.log(dcWordArray instanceof CryptoJS.lib.WordArray); // 应该返回true - 检查对象属性:WordArray实例会包含
words(存储数据的Uint32数组)和sigBytes(有效字节数)两个核心属性,打印这两个属性看看是否存在:console.log(newWordArray.words, newWordArray.sigBytes); console.log(dcWordArray.words, dcWordArray.sigBytes);
如果这两个属性都存在且符合预期,就说明它们是正确的WordArray类型。
问题2:将WordArray以ArrayBuffer形式发送到Drive API
首先需要把WordArray正确转换成ArrayBuffer,然后在fetch请求中设置正确的Content-Type和body格式:
1. 编写WordArray转ArrayBuffer的工具函数
function wordArrayToArrayBuffer(wordArray) { const arrayOfWords = wordArray.hasOwnProperty('words') ? wordArray.words : []; const length = wordArray.hasOwnProperty('sigBytes') ? wordArray.sigBytes : arrayOfWords.length * 4; const uInt8Array = new Uint8Array(length); let index = 0; for (let i = 0; i < Math.ceil(length / 4); i++) { const word = arrayOfWords[i]; uInt8Array[index++] = word >> 24; uInt8Array[index++] = (word >> 16) & 0xff; uInt8Array[index++] = (word >> 8) & 0xff; uInt8Array[index++] = word & 0xff; } // 裁剪到有效字节数 return uInt8Array.slice(0, length).buffer; }
2. 修正Drive API的PATCH请求
上传二进制内容时,要设置Content-Type: application/octet-stream(因为加密后的内容是二进制,不是text/plain),并且直接把ArrayBuffer作为body传入:
// 把加密后的WordArray转成ArrayBuffer const arrayBuffer = wordArrayToArrayBuffer(ecWordArray); fetch(`https://www.googleapis.com/upload/drive/v3/files/${fileId}`, { method: 'PATCH', headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/octet-stream' // 这里改成二进制类型 }, body: arrayBuffer // 直接传入ArrayBuffer }) .then(response => response.json()) // Drive API返回的是JSON,用json()解析更合适 .then(data => { console.log('更新成功:', data); }) .catch(err => { console.error('更新失败:', err); });
这样就能正确把加密后的二进制内容上传到Google Drive了。
内容的提问来源于stack exchange,提问作者Cherrimon Shop
相关产品推荐
相关产品推荐

