(NODEJS)解密后AES-256-GCM中断pdf,gzip,png编码

时间:2020-09-24 11:52:21

标签: javascript node.js aes-gcm

我希望能有所帮助,因为我不知道为什么我的AES-GCM中断文件编码实现。
我有一个使用1函数通过AES-256-GCM进行加密/解密的API。 (使用KEY = 32个随机字节的缓冲区)

功能如下:

const aes256gcm = (key) => {
    const ALGO = 'aes-256-gcm';

    const encrypt = (str) => {
        try {
            const salt = crypto.randomBytes(64);
            const iv =  crypto.randomBytes(32);
            let derivedkey = crypto.pbkdf2Sync(key, salt, 55000, 32, 'sha512');
            const cipher = crypto.createCipheriv(ALGO, derivedkey, iv);
            let encrypted = Buffer.concat([cipher.update(str), cipher.final()]);
            const tag = cipher.getAuthTag();
            let buffer = Buffer.concat([salt, iv, encrypted]);
            encrypted = {
                tag: tag,
                buffer: buffer
            }
            return encrypted;
        } catch (e) {
            console.log(e);
        }
    };

    const decrypt = (data, authTag) => {
        try {
            const salt = data.slice(0, 64);
            const iv = data.slice(64, 96);
            const text = data.slice(96, data.length);
            authTag = new Buffer.from(authTag, 'base64');
            let derivedkey = crypto.pbkdf2Sync(key, salt, 55000, 32, 'sha512');
            let decipher = crypto.createDecipheriv(ALGO, derivedkey, iv);
            decipher.setAuthTag(authTag);
            let decrypted = decipher.update(text, 'binary') + decipher.final();
            return decrypted;
        } catch (e) {
            console.log(e);
        }
    };

    return {
        encrypt,
        decrypt
    };
};

使用此代码,我将结果加密并写入文件:

const aesCipher = aes.aes256gcm(aes.loadKey(path.resolve(__dirname, `key`)));
            const encrypted = aesCipher.encrypt(file.data);
            if (encrypted !== undefined) {
                fs.writeFile(`${file.name}.enc`, encrypted.buffer, function (err) {
                    if (err) return console.log(err);
                    console.log(`${file.name}.enc successfully created`);
                });
            }

最后我解密并将内容写入文件:

const aesCipher = aes.aes256gcm(aes.loadKey(path.resolve(__dirname, `key`)));
        let filename = 'test1.gz';
        let authTag = 'puI0FfV4Btiy7iPiZFbwew==';
        let encrypted = fs.readFileSync(path.resolve(__dirname, `test1.gz.enc`));
        const decrypted = aesCipher.decrypt(encrypted, authTag);
        if (decrypted !== undefined) {
            const file = fs.createWriteStream(filename);
            file.write(new Buffer.from(decrypted, 'ascii'), function (err) {
                if (err) return console.log(err);
                console.log(`Successfully decrypted`);
                file.close();
            });
            res.send({
                status: true,
                message: 'File is decrypted',
            });
        }

我的输入/输出文件的差异: Diff

那么,我在做什么错?我的加密过程好吗?为什么这仅适用于.txt文件?

谢谢!

1 个答案:

答案 0 :(得分:0)

我认为,如果将解密功能更新为:

,对解密功能进行很小的改动就可以解决该问题。

const decrypt = (data, authTag) => {
    try {
        const salt = data.slice(0, 64);
        const iv = data.slice(64, 96);
        const text = data.slice(96, data.length);
        authTag = new Buffer.from(authTag, 'base64');
        let derivedkey = crypto.pbkdf2Sync(key, salt, 55000, 32, 'sha512');
        let decipher = crypto.createDecipheriv(ALGO, derivedkey, iv);
        decipher.setAuthTag(authTag);
        let decrypted = Buffer.concat([decipher.update(text), decipher.final()]);
        return decrypted;
    } catch (e) {
        console.log(e);
    }
};

我认为以前的实现没有正确地将非文本文件的结果连接起来。