【发布时间】:2019-05-16 16:47:02
【问题描述】:
我试图为节点的内置加密模块(特别是 scrypt)找到比较或验证功能,因为我使用的大多数密码散列模块都有这样的功能。然后,我发现了为什么这是一项不可能完成的任务:使用这些算法生成的所有哈希使用相同的参数生成相同的字符串(技术上是缓冲区)。许多crypto 的散列函数就是这种情况,包括它的pbkdf2 实现。
为什么这样安全?密码/消息散列函数的全部(现代)点不是您不能使用相同的输入再次生成相同的密码/消息吗?这就是各种 bcrypt 模块的工作方式,以及 scrypt 的原始版本,内置版本,我要问的那个,就是从中派生出来的。
例如:
let scryptHash1;
let scryptHash2;
let scryptHash3;
let pbkdfHash1;
let pbkdfHash2;
let pbkdfHash3;
const key1 = 'my secret key';
const key2 = 'my other secret key';
const salt = 'my salt';
crypto.scrypt(key1, salt, 16, hash => scryptHash1 = hash);
crypto.scrypt(key1, salt, 16, hash => scryptHash2 = hash);
crypto.scrypt(key2, salt, 16, hash => scryptHash3 = hash);
scryptHash1.toString() === scryptHash2.toString(); // true
scryptHash1.toString() === scryptHash3.toString(); // false
crypto.pbkdf2(key1, salt, 16, 16, 'sha256', hash => pbkdfHash1 = hash);
crypto.pbkdf2(key1, salt, 16, 16, 'sha256', hash => pbkdfHash2 = hash);
crypto.pbkdf2(key2, salt, 16, 16, 'sha256', hash => pbkdfHash3 = hash);
pbkdfHash1.toString() === pbkdfHash2.toString(); // true
pbkdfHash1.toString() === pbkdfHash3.toString(); // false
我最初在Cryptography 上提出了这个问题,因为我更关心安全性,因为我想从bcrypt 移动到scrypt。然而,正如多人指出的那样,正如我所担心的那样,问题更多的是关于 API 设计。话虽如此,任何可接受的答案都应该包括为什么这种方法是安全的,或者足够安全以进行切换(承认“足够安全”永远不够安全)。我的专业是安全,但我现在是一名网络开发人员,安全一直在变化,尽管核心概念基本保持不变。
【问题讨论】:
-
你为什么不期待呢?如果哈希值不一致,您将如何检查用户的输入是否与存储的哈希值相对应?
-
正如我所说,我见过的大多数密码哈希库,至少在节点上,都有比较或验证功能。
-
那么你认为这些工作如何?
标签: node.js cryptography scrypt