【问题标题】:how can I get the String from hashCode如何从 hashCode 中获取字符串
【发布时间】:2017-07-04 08:40:08
【问题描述】:

我正在做一个项目,我获得了密码字段值的 hashCode 并将该 hashCode 存储在 DB 中以用于安全目的。现在我想从 hashCode 中恢复密码。我该怎么做它? 是否可以从 hashCode 中取回 String 值?如果不是,谁能建议我以任何其他格式存储我的密码的更好方法?

【问题讨论】:

标签: java security passwords password-protection password-encryption


【解决方案1】:

你知道几个对象可以有相同的 hash(),正如 Object.hashCode() 的 java 文档中提到的那样

要求两个对象不相等 * 根据 {@link java.lang.Object#equals(java.lang.Object)} * 方法,然后在每个对象上调用 {@code hashCode} 方法 * 两个对象必须产生不同的整数结果。

很明显,你不能从相同的哈希码中恢复不同的对象,所以根本不可能,简单的逻辑。

【讨论】:

    【解决方案2】:

    散列是一个单向函数(至少应该是),因此您无法从散列中恢复密码。

    但是,您可以将相同的哈希应用于任何字符串并将其与密码的哈希进行比较,以便检查它们是否匹配。

    通过良好的散列,两个字符串具有相同散列的可能性非常低,因此您可以比较密码的散列(您可以存储)和另一个字符串的散列以确定它们是否相同。

    另一点是hashCode 不是产生这种哈希的好方法,因为我们可以很容易地拥有两个具有相同哈希码的对象。可以使用PBKDF2BCrypt等实现。

    【讨论】:

      【解决方案3】:

      一种技术是暴力破解。只需遍历所有可能的密码。如果哈希算法的计算成本不高的话,你可以通过一个惊人的数字。

      如果它真的是String.hashCode,那么这在密码学上是不安全的。不是由一个长镜头。正如 ΦXocę 웃 Пepeúpa ツ 的回答所暗示的那样,您可能可以手动回溯到一个(许多)可能的密码。

      你应该怎么做?使用众所周知的加密哈希。最好是计算成本高的一种,例如 bcrypt。您还应该对密码进行加盐(在散列之前与密码组合的随机数,以防止使用紧凑的预先计算的查找表(彩虹表)来破解批量)。基本上使用别人的库/系统。

      【讨论】:

        【解决方案4】:

        不是一个好主意,hashCode 永远不应该用作证明对象相等性的标识符...

        考虑一下:

        System.out.println("Aa".hashCode());
        System.out.println("BB".hashCode());
        

        两者具有相同的 HashCode 2112 但持有完全不同的信息

        【讨论】:

        • 使用哈希码作为存储密码完全依赖于这种技术。更重要的标准是密码不应该是可恢复的,并且哈希码不应该是可逆的。
        • 所以如果你的密码是 Aa,你也可以加入 BB 吗?
        • 当然,这就是哈希码的工作原理:它们是从大值空间到小值空间的映射,因此不可逆,正如我刚才所说,这才是真正的意义所在。密码的不可逆性是company-busting issue 的解决方案。您的示例几乎不现实,但根据定义,地球上的每个安全系统都使用密码哈希而不是密码加密。
        • 再补充一点,密码通常不会像hashCode 那样在int 中进行散列处理,因此重复值的“机会”比使用String.hashCode 更小。例如,使用MD5 会创建一个更复杂的散列,具有更大的组合可能性。
        猜你喜欢
        • 1970-01-01
        • 2021-04-15
        • 2011-11-30
        • 2017-07-28
        • 2012-07-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多