【发布时间】: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