2014-02-20 142 views
9

虽然我理解哈希和盐度密码,但似乎我有一些误解。我正在为nodejs中的我的网站创建一个用户帐户系统。密码哈希+盐如何工作

我理解它的方式是,当用户创建密码时,我们生成一个随机盐,将其附加到密码,然后对该字符串进行哈希处理。我们还可以添加一个工作因子,以使哈希缓慢运行并抵御暴力攻击。我们将salt和散列一起存储在数据库中,并验证登录尝试,我们使用存储的盐和尝试的密码重复上述过程(在服务器上),并检查哈希是否匹配。

nodejs中的bcrypt模块似乎与我对散列的解释不一致。这是从http://codetheory.in/using-the-node-js-bcrypt-module-to-hash-and-safely-store-passwords/一个例子

var salt = bcrypt.genSaltSync(10); 
var hash = bcrypt.hashSync("my password", salt); 

首先,为什么是工作因素应用到盐,而不是哈希?如果有人用暴力攻击,他们会运行哈希函数正确吗?哈希函数我们需要慢吗?

我也通过验证与bcrypt困惑:

bcrypt.compareSync("my password", hash); 

我们需要散列是即使两个用户选择相同的密码是唯一的,这是正确的盐点?那么,为什么我们不这样做呢?

bcrypt.compareSync("my password"+salt, hash); 
+0

盐的主要目标是防止彩虹表攻击,即预先计算的盐到密码的映射,从而降低破解到'originalPassword = rainbowTable [hash]'的复杂度。许多盐甚至更好,但并非所有系统都使用多于一种盐。 – FakeRainBrigand

回答

2

salt包含回合数,以便bcrypt.hash(Sync)函数知道它有多少轮办。 因此,hash不是一个简单的散列,而是一个嵌入式容器salt

+1

好吧,这是有道理的。那么这是否意味着我不需要在我的数据库中存储盐字符串?我只需要存储'hashSync('pw',salt)'的返回值,并且它嵌入了salt,这就是为什么我们没有明确地将salt传递给'compareSync'? – gloo

+0

只需存储'hash' –

2

SALT是2个数的度数(从4到31) - 函数创建哈希的迭代工作循环。 bcrypt取盐,乘盐2次。并取这个值来对我们的字符串执行解码函数的总次数。它是“rounder”循环在bcrypt函数中。 当你每次:

bcrypt.hashSync("my password", salt) 

bcrypt创造新的“随机”的字符串,每次使用相同的输入字符串,并使用相同的salt我们采取不同的输出字符串,它的工作bcrypt的核心思想功能,并且这个总结果我们将保存到我们的基地。 然后我们使用:

bcrypt.compareSync("my password", hash); 

而且compareSync计算哈希值,如果从字符串“我的密码”创建。如果我们将功能compareSync加入到我们的字符串中(“我的密码”),我们将更改已启动的字符串,并且绝不会以这种方式采用true。因为bcrypt会比较hash如果已创建像这样:

bcrypt.hashSync("my password"+salt, salt); 

这是我们应该使用这种结构方式:

  • 创建哈希过程中创建的用户数据: var salt = bcrypt.genSaltSync(10); var hash = bcrypt.hashSync("my password", salt);
  • 节省hash到DB
  • 登录时的下一步验证用户喜欢:

    bcrypt.compareSync("my password", hash);

没有任何salt或参数。