【问题标题】:What have in mind when they say that it need to store password hash in the database?当他们说需要将密码哈希存储在数据库中时,您会想到什么?
【发布时间】:2012-10-10 21:17:51
【问题描述】:

我是网络开发的新手。我使用 Java 并尝试开发具有注册功能的简单试点应用程序。为了安全起见,我不想将用户密码显式存储在数据库中。

有人告诉我有必要存储密码哈希。但是,这是什么意思? 什么是哈希? 我知道在 Java 中,每个对象都有一个唯一的哈希码。这是我需要的吗?我需要调用密码的方法hashcode()吗?也许我只需要应用加密方法?还是先获取我密码的哈希码,然后再加密?

我认为安全存储密码有很多选择和方法。但是在这种情况下,哈希到底是什么意思呢?

【问题讨论】:

标签: java encryption hash hashcode password-encryption


【解决方案1】:

这意味着当用户在注册时输入密码时,您不会以纯文本形式存储用户密码,而是使用不可逆哈希算法(例如 MD5)对密码进行哈希处理并将此值保存到数据库中。

这是一个解释如何 How can I generate an MD5 hash?

在检查密码时,将用户在登录表单中输入的密码使用相同的算法进行哈希处理,然后与保存在数据库中的密码进行比较。

【讨论】:

  • 现在 SHA-256 或 512 是比 MD5 更好的选择。
  • @IanRoberts Plain SHA-2 在密码散列方面几乎和 MD5 一样糟糕。请改用 scrypt、bcrypt 或 PBKDF2。
【解决方案2】:

根据您需要用户密码的安全程度,您可能需要使用cryptographic salt 和拉伸。

Salt 意味着在散列之前在密码中添加一些随机字节。这样,如果两个用户选择相同的密码,那么他们将拥有不同的哈希值。将盐与哈希一起存储,并在每次需要重新计算哈希时使用。

hash <- SHA256(password + salt)  // + is concatenation

加盐意味着如果您的一个用户的密码被破解,那么其他具有相同密码的用户将在数据库中拥有不同的哈希值,从而防止攻击者立即知道他们的密码。为了提高安全性,盐的长度可以为 16 个字节。

拉伸意味着多次重复计算,因此运行大约需要 0.1 秒。十分之一秒的延迟不会影响您的用户,但意味着任何试图猜测密码的人每秒只能猜测十次。

hash <- SHA256(password + salt)
do 5000 times
  hash <- SHA256(hash + salt)
end do

调整号码5000以获得您想要的延迟。

【讨论】:

    【解决方案3】:

    您可能正在寻找 SQL 的 PASSWORD 功能。这是在您的数据库中存储任何加密密码的最简单的解决方案。

    你去:http://dev.mysql.com/doc/refman/5.1/en/password-hashing.html

    或者就在这里:http://www.google.com/search?q=sql+function+password+hash

    【讨论】:

      【解决方案4】:

      我建议您查找有关 PBKDF2 的信息,而不是所有选项。 PBKDF2 是用 Java 实现的。

      byte[] salt = new byte[256 / Byte.SIZE];
      SecureRandom defaultRNG = new SecureRandom();
      defaultRNG.nextBytes(salt);
      
      SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
      KeySpec ks = new PBEKeySpec(password,salt,2000,256);
      SecretKey s = f.generateSecret(ks);
      final byte[] result = s.getEncoded();
      

      您应该同时存储saltresult。执行相同的计算和二进制比较结果以验证密码。我使用了 256 位盐和输出大小。在 PBKDF2 中使用 SHA-1 不是问题。 2000 次迭代计数应该是最小值,如果您的应用程序可以处理 CPU 要求,请使用更高的值。

      【讨论】:

        【解决方案5】:

        存储散列而不是密码(无论是明文还是加密)的主要思想是散列是不可逆的 - 任何人都可以访问数据库和/或加密密钥,但仍然不知道密码。这不仅仅是关于混淆/加密。散列用于丢失允许恢复密码并使其无法以任何方式识别密码的信息。哈希是您希望使用的任何函数,它可以保证所需程度的唯一性和不可逆性 - java 哈希码很容易复制,MD5 和 SHA1 有已知的弱点。现在推荐例如 SHA-256。

        【讨论】:

        • MD5 和 SHA-1 中的已知弱点与密码散列无关。但是所有这些(包括 SHA-2)的快速性能使得普通散列成为密码散列的糟糕选择。你需要某种伸展运动。
        猜你喜欢
        • 1970-01-01
        • 2011-05-27
        • 2012-11-25
        • 2012-01-30
        • 2011-10-23
        • 1970-01-01
        • 2011-01-17
        • 2019-03-17
        • 1970-01-01
        相关资源
        最近更新 更多