【问题标题】:Invalid length key or iv in node.js cryptonode.js 加密中的长度密钥或 iv 无效
【发布时间】:2021-06-17 16:51:39
【问题描述】:

我知道这个主题有几个答案,但我对详细信息密钥长度有疑问。

我想用 CTR 加密 AES 算法中的数据。加密长度为 256 位。

如果我通过密钥长度 256 和 IV 长度 16 对数据进行加密,则会收到错误 Invalid key length。我认为 IV 必须是相同的密钥长度。我将 IV 的长度更改为 256,但出现错误 Invalid iv length。我发现 IV 必须是 16 位长。

只有当我的密钥是 16 位并且我的 IV 是 16 位长时,我的代码才有效。所以我的代码没有用 256 位长度加密。

我的代码

const crypto = require('crypto');
let key = crypto.randomBytes(16).toString('hex'); // Key is static
let iv = crypto.randomBytes(16);

let cipher = crypto.createCipheriv('aes-256-ctr', process.env.KEY, iv);
let encrypte = cipher.update("Example_data", 'utf-8', 'hex');
encrypte += cipher.final('hex');

密钥长度为 256 位的数据如何加密?

【问题讨论】:

    标签: node.js encryption cryptography cryptojs


    【解决方案1】:

    首先:AES 使用 16 字节的 IV(对应于 AES 块大小)和 16、24 或 32 字节的密钥。在发布的代码中指定了aes-256-ctr,因此需要一个 256 位 = 32 字节的密钥。

    这正是所应用的密钥的大小,而不是您假设的 16 字节,这就是代码首先执行的原因(至少如果未定义的 process.env.KEYkey 替换):@ 987654325@ 创建一个 16 字节的缓冲区,toString('hex') 将其转换为十六进制字符串,加倍大小为 32 个字节(因为缓冲区中的 1 个字节由 2 个字符(因此 2 个字节)表示字符串)。所以从技术上讲,使用 UTF-8 编码(crypto.createCipheriv() 的默认值),这会产生一个 32 字节的密钥,可用于aes-256-ctr。但是这个key中的每个字节只能取16个值(对应数字0-9和af),对应1632 = 25616 = 2128 个可能的值,因此不是 256,而是只有 128 位安全强度。

    您可以通过直接使用密钥的二进制数据来防止降低安全强度,因此crypto.randomBytes(32)。这里每个字节可以取 256 个不同的值,这对应于 32 个字节的密钥到 25632 = 2256 个可能的值,因此是 256 位的安全强度。如果密钥是十六进制编码的,则不能是 UTF8 编码的,而是十六进制解码的。

    如果密钥是派生的,例如使用密钥派生函数,十六进制编码可能会导致跨平台的另一个问题。如果一个平台将大写字母用于十六进制编码,而另一个小写字母则将产生 不同的键。

    长话短说:避免将十六进制字符串的 UTF8 编码数据用作密钥(或至少了解其中的含义)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-18
      • 2016-03-20
      • 2015-08-13
      • 1970-01-01
      相关资源
      最近更新 更多