gpt4 book ai didi

javascript - 使用 crypto-js 对文件进行 AES 加密和解密

转载 作者:行者123 更新时间:2023-11-28 03:07:04 25 4
gpt4 key购买 nike

我目前有这样的需求,但是无法解密加密文件,生成的文件总是损坏,打不开,不知道问题出在哪里。下面贴出的代码是我在VUE中使用的代码。

Encode() {
let CryptoJS = require("crypto-js");
this.file_mime = this.file.type;
this.file_name = this.file.name;
let reader = new FileReader();
reader.onload = () => {
let key = "1234567887654321";
// let wordArray = CryptoJS.lib.WordArray.create(reader.result);
// let plaintext = CryptoJS.enc.Hex.stringify(wordArray);
let encrypted = CryptoJS.AES.encrypt(reader.result, key).toString();

this.file2 = new Blob([encrypted], {
type: this.file_mime
});
const a = document.createElement("a");
const url = window.URL.createObjectURL(this.file2);
const filename = this.file_name;
a.href = url;
a.download = filename;
a.click();
window.URL.revokeObjectURL(url);
};
reader.readAsBinaryString(this.file);
}

Decode() {
let CryptoJS = require("crypto-js");
let reader = new FileReader();
reader.onload = () => {
let key = "1234567887654321";
let decrypted = CryptoJS.AES.decrypt(reader.result, key).toString(CryptoJS.enc.Utf8)
this.file2 = new Blob([decrypted], {type: this.file_mime});
const a = document.createElement("a");
const url = window.URL.createObjectURL(this.file2);
const filename = this.file_name;
a.href = url;
a.download = filename;
a.click();
window.URL.revokeObjectURL(url);
};
reader.readAsBinaryString(this.file);
}

最佳答案

在 JavaScript 中,数组有多种类型: ArrayArrayBuffertyped arrays 。 CryptoJS 还使用 WordArray 。您必须在这些类型之间正确进行转换。

对于加密, FileReader.readAsBinaryString 应替换为 FileReader.readAsArrayBuffer ,后者以 ArrayBuffer 的形式从文件中返回二进制数据。在加密方法中,ArrayBuffer可以转换为WordArray,可以直接由CryptoJS.AES.encrypt处理。 CryptoJS.AES.encrypt 将密文返回为 CipherParams 对象 ( here ),该对象使用 toString() 转换为 OpenSSL 中的 Base64 编码字符串格式。该字符串可用于直接创建 blob。

注意:由于 key 在 CryptoJS.AES.encrypt 中作为字符串传递,因此它被解释为密码,并使用 OpenSSL 使用的相同算法生成随机 8 字节盐,从它与密码、 key 和 IV 一起生成。密文前面是一个 16 字节的 block ,由 Salted__ 的 ASCII 编码组成,后面是 8 字节的 salt,整个内容都是 Base64 编码的。因此,在此 OpenSSL 格式中,Base64 编码数据以 U2FsdGVkX1herehere 开头。

加密方法的变化:

function encrypt(input) {
var file = input.files[0];
var reader = new FileReader();
reader.onload = () => {
var key = "1234567887654321";
var wordArray = CryptoJS.lib.WordArray.create(reader.result); // Convert: ArrayBuffer -> WordArray
var encrypted = CryptoJS.AES.encrypt(wordArray, key).toString(); // Encryption: I: WordArray -> O: -> Base64 encoded string (OpenSSL-format)

var fileEnc = new Blob([encrypted]); // Create blob from string

var a = document.createElement("a");
var url = window.URL.createObjectURL(fileEnc);
var filename = file.name + ".enc";
a.href = url;
a.download = filename;
a.click();
window.URL.revokeObjectURL(url);
};
reader.readAsArrayBuffer(file);
}

注意:由于加密数据是Base64编码的,并且Base64编码有一个 overhead of 33% ,因此加密数据相对于未加密数据来说相应更大。

对于解密,FileReader.readAsBinaryString 应替换为 FileReader.readAsText ,因为加密数据存储为 Base64 编码字符串(OpenSSL 格式),可以直接传递给 CryptoJS。 AES.解密。该字符串隐式转换为 CipherParams 对象( here ,或者可以显式传递 CipherParams 对象)。 CryptoJS.AES.decryptWordArray 形式返回解密数据,因此需要转换为类型化数组或 ArrayBuffer 才能创建 blob。为此,可以使用以下函数:

function convertWordArrayToUint8Array(wordArray) {
var arrayOfWords = wordArray.hasOwnProperty("words") ? wordArray.words : [];
var length = wordArray.hasOwnProperty("sigBytes") ? wordArray.sigBytes : arrayOfWords.length * 4;
var uInt8Array = new Uint8Array(length), index=0, word, i;
for (i=0; i<length; i++) {
word = arrayOfWords[i];
uInt8Array[index++] = word >> 24;
uInt8Array[index++] = (word >> 16) & 0xff;
uInt8Array[index++] = (word >> 8) & 0xff;
uInt8Array[index++] = word & 0xff;
}
return uInt8Array;
}

注意:将 WordArray 转换为 Utf8 字符串(如发布的代码中所示)是不可能的,并且通常会损坏数据,因为二进制数据(例如来自 pdf)包含任意字节通常不对应于 Utf8 编码的序列(因为二进制数据不包含可打印字符), here

解密方法的变化:

function decrypt(input) {
var file = input.files[0];
var reader = new FileReader();
reader.onload = () => {
var key = "1234567887654321";

var decrypted = CryptoJS.AES.decrypt(reader.result, key); // Decryption: I: Base64 encoded string (OpenSSL-format) -> O: WordArray
var typedArray = convertWordArrayToUint8Array(decrypted); // Convert: WordArray -> typed array

var fileDec = new Blob([typedArray]); // Create blob from typed array

var a = document.createElement("a");
var url = window.URL.createObjectURL(fileDec);
var filename = file.name.substr(0, file.name.length - 4) + ".dec";
a.href = url;
a.download = filename;
a.click();
window.URL.revokeObjectURL(url);
};
reader.readAsText(file);
}

关于javascript - 使用 crypto-js 对文件进行 AES 加密和解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60520526/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com