我可以使用Object#hashCode来存储密码的哈希值吗?

8 java security hash

为了保存文件,我定义了以下方法

public int encrypt(String fileName, String password) {
   return (fileName.concat(password)).hashCode();
}
Run Code Online (Sandbox Code Playgroud)

这将返回存储在文件中的哈希值.每当用户想要访问该文件时,他输入密码,如果生成相同的散列,则他可以访问该文件.

我想这不是很安全,但它有多安全?String#hashCode生成具有两个不同输入的相同哈希的机会有多高?

编辑:

根据你的答案,我改变了代码:

public String encrypt(String password) {
        String hash = "";
        try {
            MessageDigest md5 = MessageDigest.getInstance("SHA-512");
            byte [] digest = md5.digest(password.getBytes("UTF-8"));
            hash = Arrays.toString(digest);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return hash;
    }
Run Code Online (Sandbox Code Playgroud)

所以它现在应该更好?

Jon*_*eet 17

这是个坏主意 - 您应该使用正常的加密哈希,例如SHA-1,就像NullUserException所说的那样.

但是,它是可移植的 - 用于String.hashCode()明确说明算法的文档.任何正确实现文档的JRE都应该提供相同的哈希码.但是,由于hashCode()算法的工作方式,很容易找到一个生成任何特定哈希码的字符串 - 即使是以特定前缀开头的代码 - 因此知道哈希的攻击者可以非常轻松地攻击您的应用程序.加密哈希旨在使得难以设计匹配特定哈希的密钥.


tob*_*yer 5

依靠非加密函数来提供安全相关目的通常是一个坏主意.由于您无法确定使用哪个实现(并将在未来使用)来计算字符串的哈希码,因此您应该更喜欢加密安全哈希码算法.我建议使用SHA-1或SHA-256.http://www.bouncycastle.org/具有许多哈希算法的实现.


Gil*_*il' 5

String.hashCode不适合散列密码.您需要加密哈希.

String.hashCode被设计为非常快速的计算.它的主要用途是用于哈希表中的密钥.对于这种用途,偶尔的碰撞不是问题.加密哈希计算速度较慢,但​​根据定义,没有人知道如何为良好的加密生成冲突.

更重要的是,鉴于其价值password.hashCode(),可以找到password(高可信度,但不确定,因为许多密码具有相同的哈希值).这不是你想要发生的事情.另一方面,加密哈希的设计使得无法找到知道哈希的密码(从数学上讲,没有人知道如何在其生命周期中从哈希中找到密码).

Java标准库中提供了加密哈希,通过java.security.MessageDigest.

补充:还有一个复杂因素:直接哈希密码是个坏主意.原因是攻击者可以尝试所有可能的密码(例如字典单词,人名等).这个问题的标准解决方案是在计算哈希值之前将密码与一个名为salt的随机字符串连接起来:你做的就像.盐使得攻击者预先计算可能密码的所有哈希值是不切实际的.sha.digest((salt+password).getBytes())

通常是当用户选择他/她的密码时随机生成的盐,并且它存储在用户数据库中的密码哈希旁边,但是根据您显示的方案,没有这样的东西.根据你的设计,使用文件名作为盐是合理的:fileName.concat(encrypt(fileName + password)).

  • 你找不到某些密码(毕竟,会有很多字符串都散列到相同的值) - 但是你可以找到一个给出相同散列的字符串. (2认同)