我很难找到一些信息。有谁知道从cipher.getAuthTag() (--> 返回 MAC) 返回的值是否可以公开显示?
TL;博士
消息验证码可以公开可见,还是需要像密码一样保密?
一些背景,我正在尝试加密文件。我找到了这个帮助我入门的 stackoverflow 问题和答案。https://stackoverflow.com/a/27345933/11070228
在对 nodejs 文档进行了一些研究之后,我发现答案使用了一个已弃用的函数。创建密码。要使用的新函数应该是createCipheriv。
因此,为了使用新的 createCipheriv,我使用文档编写了一个新的加密和解密函数,类似于帖子中使用新的 createCipheriv 函数的那个。编写解密函数后,我得到一个错误是
错误:不受支持的状态或无法验证数据
在谷歌搜索这个问题之后,它把我带到了这个github 帖子。简而言之,它表示解密文件需要使用密码生成的 authTag。
我不知道这个 authTag 是什么,我认识的任何人也不知道。所以我开始用谷歌搜索它,它让我看到了这篇博文。它指出
authTag 是在加密期间计算的消息验证码 (MAC)。
这是一篇关于什么是消息验证码的维基百科文章。
所以。这是我的问题。消息验证码可以公开可见,还是需要像密码一样保密?
我的代码不那么相关,但可能会帮助某人使用 createCipheriv 和 createDecipheriv 创建加密和解密。
加密
const crypto = require('crypto');
const fs = require('fs');
// const iv = crypto.randomBytes(32).toString('hex');
// EDIT - based on @President James K. Polk. The initialization vector should be 12 bytes long
// const iv = crypto.randomBytes(6).toString('hex');
// EDIT - based on @dsprenkels. I misunderstood @President James K. Polk
const iv = crypto.randomBytes(12).toString('hex');
const privateKey = 'private key that is 32 byte long';
const cipher = crypto.createCipheriv('aes-256-gcm', privateKey, iv);
const filename = 'somefile.txt';
const encFilename = 'somefile.txt.enc';
const unencryptedInput = fs.createReadStream(filename);
const encryptedOutput = fs.createWriteStream(encFilename);
unencryptedInput.pipe(cipher).pipe(encryptedOutput);
encryptedOutput.on('finish', () => {
const authTagAsHex = cipher.getAuthTag().toString('hex'); // <-- can this be public
console.log(authTagAsHex);
});
解密
const crypto = require('crypto');
const fs = require('fs');
// const publicIV = 'same iv generated during encryption crypto.randomBytes(32).toString("hex")';
// EDIT - based on @President James K. Polk. The initialization vector should be 12 bytes long
// const publicIV = 'same iv generated during encryption crypto.randomBytes(6).toString("hex")';
// EDIT - based on @dsprenkels. I misunderstood @President James K. Polk
const publicIV = 'same iv generated during encryption crypto.randomBytes(12).toString("hex")';
const authTag = 'same authKey generated from cipher.getAuthTag().toString("hex")';
const privateKey = 'private key that is 32 byte long';
const decipher = crypto.createDecipheriv('aes-256-gcm', privateKey, publicIV);
decipher.setAuthTag(Buffer.from(authTag, 'hex'));
const filename = 'somefile.txt';
const encFilename = 'somefile.txt.enc';
const readStream = fs.createReadStream(encFilename);
const writeStream = fs.createWriteStream(filename);
readStream.pipe(decipher).pipe(writeStream);