gpt4 book ai didi

node.js - Node crypto.createCipheriv ('aes-256-gcm' , ...).getAuthKey() 的值可以公开吗?

转载 作者:行者123 更新时间:2023-12-04 14:13:30 26 4
gpt4 key购买 nike

我很难找到一些信息。有谁知道值是否从 cipher.getAuthTag() 返回 (--> 返回 MAC) 可以公开吗?

TL;DR

Can a message authentication code be publicly visible, or does this need to be kept secret like a password?



一些背景,我正在尝试加密文件。我发现这个 stackoverflow 问题和答案可以帮助我入门。 https://stackoverflow.com/a/27345933/11070228

在 nodejs 文档中做了一些研究后,我发现答案使用了一个已弃用的函数。 createCipher .要使用的新函数应该是 createCipheriv .

因此,为了使用新的 createCipheriv,我使用文档编写了一个新的加密和解密函数,类似于使用新 createCipheriv 函数的帖子中的那个。写完解密函数后,我得到一个错误是

Error: Unsupported state or unable to authenticate data



在谷歌搜索这个问题后,它把我带到了这个 github post .简而言之,它表示需要使用密码生成的 authTag 来解密文件。

我不知道这个 authTag 是什么,我认识的任何人也不知道。所以我开始在谷歌上搜索它,它让我找到了这个 blogpost .它指出

The authTag is the message authentication code (MAC) calculated during the encryption.



这是一个 wikipedia article什么是消息验证码。

所以。这是我的问题。消息身份验证代码是否可以公开显示,或者是否需要像密码一样保密?

我的代码,不那么相关,但可能会帮助某人使用 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);

最佳答案

是的。 MAC被认为是公共(public)的。

通常,消息身份验证代码被认为是公开的。消息身份验证代码在您提供的 key 下对(加密的)消息进行身份验证。换句话说,接收方使用它来检查密文在传输过程中是否没有改变。在您的情况下,只要 key 保持 secret ,攻击者就无法使用 MAC。

当存储密文时,MAC 通常放在密文旁边(就像 IV 一样)。

顺便说一句,在您的情况下,您是随机生成 IV。这很好,但请注意,可以在同一 key 下安全加密的消息数量相当small .如果 IV 用于多条消息(甚至一次!),则该方案的完整安全性将失效。真的,你可能想要这个:

const iv = crypto.randomBytes(12);

关于node.js - Node crypto.createCipheriv ('aes-256-gcm' , ...).getAuthKey() 的值可以公开吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62438124/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com