我正在尝试构建一个简单的密码验证器,其中密码已经使用SHA-256进行了哈希。
我在线发现了几个计算器(http://onlinemd5.com/),其中“密码”为“5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8”
我尝试了其他一些预期结果的密码。
所以我试着实现一套相当简单的代码(或者我认为)
String pswd="password";
String storedPswd="5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8";
//first as a byte[]
Arrays.equals(hashWord(pswd),storedPswd.getBytes("UTF-8") );
...
private byte[] hashWord(String word) {
try {
return MessageDigest.getInstance("SHA-256").digest(word.getBytes("UTF-8"));
} catch (Exception e) {
throw new BadCredentialsException("Could not hash supplied password", e);
}
}
我也尝试过没有成功。
return storedPswd.toUpperCase().equals(DigestUtils.sha256Hex(password));
Apache编解码器库(v1.10)和Java 1.6给了我:
113459EB7BB31BDDEE85ADE5230D6AD5D8B2FB52879E00A84FF6AE1067A210D3
而不是
5E884898DA28047151D0E56F8DC6292773603D0D6AABBDD62A11EF721D1542D8
我错过了什么?
解决方案(输入错误):
更新测试代码:
String passwordSHA="5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8";
String complexSHA="8849fb9b221ddec0117e2796d16929179accf3a6012f738e1ed6c11af9cc2081";
@Test
public void testDigest() throws InterruptedException{
System.out.println("Starting Digest test");
String complexPassword = "a7$h1UC8";
try {
Assert.assertTrue(authenticateUser(complexPassword, complexSHA));
Assert.assertTrue(authenticateUser("password", passwordSHA));
Assert.assertTrue( hashWord(complexPassword).equals(complexSHA) );
} catch (Exception e) {
Assert.fail();
}
}
public boolean authenticateUser(String word, String stored) throws Exception {
String apache2Pswd = hashApache(word);
System.out.println(apache2Pswd);
return stored.equals(apache2Pswd);
}
private String hashApache(String pswd){
return DigestUtils.sha256Hex(pswd);
}
public static String hashWord(String word) throws Exception{
byte[] digest = MessageDigest.getInstance("SHA-256").digest(word.getBytes("UTF-8"));
StringBuilder sb = new StringBuilder();
for (byte b : digest) {
sb.append(String.format("%02x", b));
}
System.out.println(sb.toString());
return sb.toString();
}
结果:
Starting Digest test
8849fb9b221ddec0117e2796d16929179accf3a6012f738e1ed6c11af9cc2081
5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
8849fb9b221ddec0117e2796d16929179accf3a6012f738e1ed6c11af9cc2081
答案 0 :(得分:3)
您发布的hashWord
方法不正确,无法编译(这是您的实际代码吗?);它没有返回值。
有了这个:
byte[] digest = MessageDigest.getInstance("SHA-256").digest("password".getBytes("UTF-8"));
for (byte b : digest) {
System.out.printf("%02x", b);
}
我确实得到了预期的输出:
5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
输出113459eb7bb31bddee85ade5230d6ad5d8b2fb52879e00a84ff6ae1067a210d3
是在字符串5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
而不是原始字符串password
上计算SHA-256哈希值时得到的。
您正在计算包含哈希值的十六进制字符串的哈希值,而不是原始密码的哈希值。
答案 1 :(得分:1)
在散列之前,没有仔细记录如何将用户输入转换为二进制的在线资源对于比较哈希值是没有价值的。
如果您的编码方法产生与其他任何东西兼容的哈希,那么最终并不重要。重要的是你一致地获得相同输入的相同哈希值(即哈希过程必须是deterministic)。