因此,我目前正在学习 SpringBoot,现在我正在尝试将密码与用户的其他数据一起存储在数据库 (MySql) 中。为了确保安全,我使用加盐哈希来存储。生成这些散列并将它们存储在数据库中工作正常,但是当我尝试通过获取盐和密码来验证密码时,我得到了不同的散列,因此得到了错误的结果。下面是我的代码。第一个:User我开始验证的类@Entitypublic class User {@Id@GeneratedValue(strategy = GenerationType.SEQUENCE)private long uID;@NotNullprivate String nname;@NotNullprivate String vname;private String email;private String telnr;@Embeddedprivate Address address;@NotNullprivate boolean isAdmin;private String hash;// Default Constructorpublic User() {}// Constructorpublic User(String name, String vname, String email, String telnr, Address address, boolean isAdmin, String password) throws NoSuchAlgorithmException { HashHelper hashHelper = new HashHelper(); this.nname = name; this.vname = vname; this.email = email; this.telnr = telnr; this.address = address; this.isAdmin = isAdmin; this.hash = hashHelper.createHash(password);}public boolean validateHash(String password) { HashHelper hashHelper = new HashHelper(); // Get the used Salt String[] parts = this.hash.split(":"); byte[] salt = parts[0].getBytes(); // Create Hash with old salt String newHash = hashHelper.getHash(password, salt); if (parts[1] == newHash) { return true; } return false;}其次,在我的课程HashHelper中,我处理与散列有关的所有事情。createHash每当存储新密码(因此,新盐)并getHash使用特定盐进行验证时,我都会使用。
1 回答

RISEBY
TA贡献1856条经验 获得超5个赞
您的问题没有实际意义,因为您不应该使用此算法来散列密码,因为它不安全。即使你没有保护任何重要的东西,用户也可能在多个地方使用相同的密码,当攻击者破解你不安全的密码表时,他们将能够在其他地方使用其中的许多密码。
使用 Argon2,或至少使用 PBKDF2 来散列密码,至少进行 10,000 轮散列。
您在这里遇到麻烦的原因是您没有存储用于散列密码的盐。没有它,您将永远无法计算出相同的哈希值。问题salts.toString()
出在createHash()
方法上:
hash=salts.toString() + ":" + sb.toString();
调用toString()
abyte[]
不会告诉您有关数组内容的任何信息。这就是为什么您不厌其烦地将摘要的结果 转换bytes
为十六进制的原因。你应该做一些类似于盐的事情。
同样,调用getBytes()
字符串只是使用您平台的默认编码对字符串进行编码。那不是你想要的。
确保equals()
在比较String
实例时使用他们的方法。==
操作员只会告诉您它们是否是相同的实例。
当存储字节数组时,您仍然需要使用良好的哈希算法来完成,我建议使用 base-64,因为它在 中有很好的支持java.util.Base64
,并且它会产生更紧凑的数组编码。
添加回答
举报
0/150
提交
取消