将哈希密码存储到Mysql

时间:2013-12-07 06:44:15

标签: php mysql

我正在研究在PHP.NET上散列数据并将密码存储到数据库。 这个网站说:

如果您要将数据存储在MySQL数据库中,请记住varchar字段在插入过程中会自动删除尾随空格。由于加密数据可以在空格(ASCII 32)中结束,因此删除会损坏数据。将数据存储在tinyblob / tinytext(或更大)字段中。

这表明哪个更好?或者我可能要问:其中一个更好吗?如果答案是肯定的,哪个? 最后我应该如何使用PDO将密码存储到db。我以为我可以像文件一样将信息写入blob行,但如果从输入中获取值,必须使用哪种方法或函数? 你能解释一下吗?

1 个答案:

答案 0 :(得分:10)

存储散列密码时,空白删除不是问题:

  • 您从不存储密码本身,而是存储哈希函数的输出。
  • 此哈希函数生成固定大小的输出(或者您可能使用可逆的加密算法)。
  • 大多数哈希函数的输出已经是固定大小的明文 [1] ,不包含任何空格。否则,您可能正在使用不用于密码散列的散列函数。
  • 固定大小的 salt 与散列输出一起存储(知道salting的密码散列函数通常使用散列密码输出salt)。
  • 如果您想要灵活并且能够在将来升级到更好的哈希函数,您还必须记住使用了哪个哈希函数。建议使用明文 [1] 获取此信息,这使得完整记录可变长度。 RFC 2307描述了这种可能的明文 [1] 存储方案。

密码应使用现代且经过验证的key-stretching算法进行哈希处理,但不能使用SHA-256或MD5等加密哈希函数进行哈希处理。合适的算法包括PBKDF2bcryptscrypt

例如,使用bcrypt对字符串“pass phrase”进行哈希处理,并且可以生成新的盐

$2a$12$PuYHvYwgKeD.hQ1Dv6nLQuxUkv5zP3lYLPHqdMOzgwPVaGGSAs07u
`-----'`-----------·······                  ·········-------'
algorithm       random salt                    password hash
parameters

整个字符串可以用作salt,因为实际的密码哈希将被切断而不能用作salt。

用于验证登录尝试的推荐工作流程:

  1. 用户提供用户名和密码。小心处理Unicode规范化和编码。
  2. 根据用户名从数据库中提取哈希密码。
  3. 解析散列密码以确定使用的算法。
  4. 使用用户密码作为输入调用正确的算法,并使用哈希密码作为salt。
  5. 如果两个哈希匹配,则用户提供了正确的密码。
  6. 建议设置新密码的工作流程:

    1. 如果用户已存在,请对其进行身份验证。
    2. 从用户处获取新密码。注意处理Unicode规范化和编码。向用户提供有关其密码强度的反馈(但不要因为禁用字符或限制性最大长度等愚蠢的要求而使用户感到沮丧。)
    3. 创建一个新的salt,它不能依赖于用户输入,如密码或用户名。
    4. 选择一个强密码哈希函数并使用新盐哈希密码。
    5. 更新数据库以存储新密码以及散列函数的标识符。
    6. 进一步评论:

      • 加密数据是二进制数据,不应存储为文本(改为使用blob)。
      • 哈希通常表示为明文而不是二进制数据,因为文本更容易存储。
      • 在许多情况下,您可以使用OpenID而不是实现自己的身份验证。例如。 Stack Exchange提供OpenID登录。因为我使用这个选项,所以我从来没有向SE披露过密码。
      • 我没有加密背景。 Information Security经常光顾 了解更多此事的人。

      [1]这里,“明文”表示可打印的ASCII字符。它没有引用密码的明文。