【问题标题】:(NODEJS) AES-256-GCM break pdf,gzip,png encoding after decryption(NODEJS) AES-256-GCM 解密后破解 pdf,gzip,png 编码
【发布时间】:2021-01-10 17:04:54
【问题描述】:

我希望我能得到帮助,因为我不知道为什么我实施 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 文件?

谢谢!

【问题讨论】:

  • 它显然大部分是正确的这一事实意味着加密/解密几乎肯定没问题。我怀疑Buffer.from(decrypted, 'ascii');任意二进制格式不是 ASCII(如果它适用于纯 ASCII 文本,那将支持我的怀疑)。我希望 JS 能够读取和写入原始二进制数据,或者如果失败,有一些编码可以用于“相当于原始字节”,例如latin-1(在 Python 中;它在技术上不使用所有 256字节,但 Python 允许它对应于前 256 个 Unicode 序数,即使在技术上没有为它们定义)。
  • 感谢您的快速回复@ShadowRanger!我已经用 latin-1 的别名编码“二进制”对此进行了测试,所以我认为这不是问题。还有其他想法吗? (它适用于长 .txt 文件)

标签: javascript node.js aes-gcm


【解决方案1】:

我认为对您的解密功能进行相当小的更改应该可以解决问题,如果您只是将其更新为:

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);
    }
};

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

【讨论】:

  • 如果我想用密码保护pdf,然后当我打开它时,它问我密钥?
  • 我不相信它是一样的。这更有可能是内置的 PDF 密码机制。
猜你喜欢
  • 2021-06-04
  • 1970-01-01
  • 2021-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-27
  • 1970-01-01
  • 2021-11-07
相关资源
最近更新 更多