2

我正在处理一个宠物项目,我想添加用户注册支持。经过一番研究,我决定在我的数据库中保存散列密码和盐,而不是原始密码。但是,我对步骤是什么以及顺序感到困惑。以下是我的假设:

注册

  1. 客户端将用户名和密码发送到服务器(https)
  2. 服务器抓取密码,生成随机盐
  3. Base64 编码盐
  4. 使用 stringify salt 对密码进行哈希处理
  5. Base64 编码密码
  6. 将密码和盐保存到数据库中

登录

  1. 客户端将用户名和密码发送到服务器(https)
  2. 服务器获取用户名和密码,从数据库中查找散列 psw 和 salt
  3. 使用盐的哈希密码,base64 编码结果
  4. 将密码与数据库中的散列 psw 进行比较
  5. 如果匹配,则验证用户

我正在实施我的系统作为我的假设,并且一切似乎都有效。但是我不确定 base64 编码部分。将密码和盐从二进制编码为字符串的目的是什么,我可以跳过这一步吗?如果我假设的过程是错误的,那么正确的步骤是什么?

PS我使用express.js作为服务器,mysql作为数据库

4

2 回答 2

3

一般的想法是好的,但我有一些评论:

  • 您应该使用 PBKDF(一种基于密码的密钥派生函数),而不是使用散列。最好使用标准化版本,即 PBKDF2。与盐一起,您还应该选择多次迭代来阻止攻击。
  • 确保您始终对用户名和密码使用相同的字符编码。
  • 密码算法应该基于二进制输入和输出。
  • 在您将二进制数据存储或加载到文本演示文稿时,您应该分别使用 Base 64 编码/解码。

所以该方案包含以下问题:

  • 使用哈希而不是 PBKDF。
  • 使用 base 64 编码的 salt 作为哈希的输入。
于 2013-01-24T21:34:47.317 回答
0

您需要了解盐的含义。它只是一种使用彩虹表对可能的蛮力攻击设置障碍的方法。这意味着一些坏人会用高计算能力尝试所有可能生成的哈希值。然后尝试从这样的哈希中提取纯文本。
因此,盐可以确保即使在这种攻击下返回的纯文本不是正确的。

例如:用户名:“Xavier_Ex” 密码:“Ilovestackoverflow”

这样的密码将被散列为“sfhj87s&^f”。现在彩虹表也可以说“sfhj87s&^f” -> Ilovestackoverflow... bleh,你的密码被破解了。

但是当加盐时,它会像“Ilovestackoverflow”->“Io*ves5tacmkove3rflow”。当这是散列时“Io * ves5tacmkove3rflow”->“dfgdfgdf”

使用“dfgdfgdf”将返回“Io*ves5tacmkove3rflow”的彩虹表..您的密码仍然是秘密的。

简而言之..你可以跳过这个,除非你确实需要这种保护。

于 2013-01-24T21:59:31.837 回答