You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何用错误密钥keyFake能解密key加密的文本?

问题原因分析与修复方案

这问题的核心是你生成AES密钥的方式完全错误,导致看似不同的key和keyFake实际上是同一个密钥,自然能解密出原文本。具体拆解如下:

1. 错误的Buffer.from调用逻辑

你写的Buffer.from({ arrayBuffer: hash, length: 32 })完全不符合Node.js的Buffer API规则。Buffer.from并不支持传入这种包含arrayBuffer属性的普通对象——当你传入这类对象时,Node.js会默认调用对象的toString()方法,将其转换为字符串"[object Object]",再基于这个固定字符串生成Buffer。

换句话说,不管hash和hashFake生成的bcrypt哈希值有多大差异,最终生成的key和keyFake都是完全相同的Buffer。用同一个密钥加密和解密,当然能得到原文本,这根本不是AES的异常,是你的密钥生成逻辑出了问题。

你可以验证一下:在代码里添加两行打印:

console.log("key hex:", key.toString('hex'));
console.log("keyFake hex:", keyFake.toString('hex'));

会看到两个输出完全一致,这就是问题的直接证据。

2. 正确的密钥生成方式

bcrypt生成的哈希是UTF-8编码的字符串,要将其转换为32字节的AES密钥,你需要正确地将字符串转换为字节序列。这里提供两种靠谱的方式:

方式一:直接截取字符串字节(简单但需注意长度)

// 将bcrypt哈希转为UTF-8字节,截取前32字节作为AES密钥
let key = Buffer.from(hash, 'utf8').slice(0, 32);
let keyFake = Buffer.from(hashFake, 'utf8').slice(0, 32);

方式二:用哈希函数生成固定长度密钥(更安全)

如果担心bcrypt哈希的字节长度不稳定,推荐用SHA-256这类哈希函数将其转换为固定32字节的密钥,保证熵的完整性:

const crypto = require('crypto');

// 用SHA-256哈希bcrypt结果,得到标准32字节AES密钥
let key = crypto.createHash('sha256').update(hash).digest();
let keyFake = crypto.createHash('sha256').update(hashFake).digest();

3. 修复后的代码效果

用上面任意一种方式修复密钥生成逻辑后,再运行代码,你会发现用keyFake解密出来的就是乱码,符合预期的加密/解密行为。

内容的提问来源于stack exchange,提问作者ErvingGoffman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:13:56