[使用crypto-js的AES加密和解密文件

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

我目前有这样的要求,但是我无法解密加密的文件,生成的文件总是损坏并且无法打开,并且我不知道问题出在哪里。下面发布的代码是我在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 aes cryptojs
1个回答
0
投票

在JavaScript中,数组有几种类型:ArrayArrayArrayBuffer。 CryptoJS也使用ArrayBuffer。您必须在这些类型之间正确转换。

对于加密,typed arrays应该替换为WordArray,后者从文件中返回二进制数据作为WordArray。在加密方法中,FileReader.readAsBinaryString可以转换为FileReader.readAsBinaryString,可以直接由FileReader.readAsArrayBuffer处理。 FileReader.readAsArrayBuffer返回作为ArrayBuffer对象(ArrayBuffer)的密文,该密文与WordArray一起转换为OpenSSL格式的Base64编码的字符串。该字符串可用于直接创建Blob。

注意:由于密钥以字符串形式在CryptoJS.AES.encrypt中传递,因此将其解释为密码短语,并使用与OpenSSL相同的算法生成随机的8个字节的盐,该算法与密码短语,密钥和IV一起从中使用生成。密文之前是一个16字节的块,该块由CryptoJS.AES.encrypt的ASCII编码组成,后跟8字节的salt,并且整个内容都是Base64编码的。因此,以这种OpenSSL格式,Base64编码的数据以CipherParamsheretoString()开头。

加密方法的更改:

CryptoJS.AES.encrypt

注意:由于加密数据是通过Base64编码的,并且Base64编码具有Salted__,因此与未加密的数据相比,加密的数据相应更大。

对于解密,U2FsdGVkX1应该替换为here,因为加密的数据存储为Base64编码的字符串(采用OpenSSL格式),可以直接传递给here。该字符串被隐式转换为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); } 对象(overhead of 33%,也可以显式传递FileReader.readAsBinaryString对象)。 FileReader.readAsText返回解密后的数据为FileReader.readAsText,因此必须转换为类型数组或CryptoJS.AES.decrypt才能创建Blob。为此,可以使用以下功能:

CipherParams

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

解密方法的更改:

CryptoJS.AES.decrypt
© www.soinside.com 2019 - 2024. All rights reserved.