我需要一些指导,我需要检查来自UI表单的密码(即Authentication
对象),我需要使用SHA-256 + constant salt
进行哈希(在进行比较之前)并输入密码使用Spring Security从DB(DB也有密码+盐)。
我希望比较使用相同的 SALT 值生成的这两个不同的散列值。我们如何在java中做到这一点?有人可以分享一下示例代码吗?
答案 0 :(得分:5)
您只需比较两个密码字符串passwordA.equals(passwordB)
...
这存在一些安全缺陷:
密码不应作为字符串处理,而应作为字符或字节数组处理:see here why
同等比较(理论上)容易受到时间攻击的影响:see a discussion about a solution in java
使用标准工具来做与安全相关的事情(即使它们似乎很简单)也许是明智之举。 Spring安全有很多工具可以帮到你。例如,请查看BCryptPasswordEncoder。出于安全目的使用经过良好测试和维护的框架总是一个好主意。
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String hashedPassword = passwordEncoder.encode(password);
...
boolean result = passwordEncoder.matches(rawPassword, hashedPassword);
:使用正确的密码哈希算法! See this Answer on SO for some proposals
SHA-256不是其中之一。 Spring Security为您提供了适合工作的工具,因此您可以使用它们。
答案 1 :(得分:0)
在我看来,您希望比较使用相同盐创建的两个单独的散列值。我对吗 ?如果是,那么这是示例程序从https://ashishpshukla.wordpress.com/2010/07/02/sample-java-code-for-password-encryption-using-secure-hash-algorithm-sha-256/
获取参考import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class PasswordEncoder {
private static PasswordEncoder instance;
private final static int ITERATION_COUNT = 5;
private PasswordEncoder() { }
public static synchronized PasswordEncoder getInstance() {
if (instance == null) {
PasswordEncoder returnPasswordEncoder = new PasswordEncoder();
return returnPasswordEncoder;
}
else
return instance;
}
public synchronized String encode(String password, String saltKey)throws NoSuchAlgorithmException, IOException {
String encodedPassword = null;
byte[] salt = base64ToByte(saltKey);
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.reset();
digest.update(salt);
byte[] btPass = digest.digest(password.getBytes("UTF-8"));
for (int i = 0; i < ITERATION_COUNT; i++) {
digest.reset();
btPass = digest.digest(btPass);
}
encodedPassword = byteToBase64(btPass);
return encodedPassword;
}
private byte[] base64ToByte(String str) throws IOException {
BASE64Decoder decoder = new BASE64Decoder();
byte[] returnbyteArray = decoder.decodeBuffer(str);
return returnbyteArray;
}
private String byteToBase64(byte[] bt) {
BASE64Encoder endecoder = new BASE64Encoder();
String returnString = endecoder.encode(bt);
return returnString;
}
public static void main(String[] args) throws NoSuchAlgorithmException, IOException {
String password = "Secrete@343";
String saltKey = "PveFT7isDjGYFTaYhc2Fzw==";
String hash1,hash2 = null;
// Assume from UI
PasswordEncoder encoder1 = PasswordEncoder.getInstance();
hash1 = encoder1.encode(password, saltKey);
System.out.println(hash1);
// Assume the same present in db
PasswordEncoder encoder2 = PasswordEncoder.getInstance();
hash2 = encoder2.encode(password, saltKey);
System.out.println(hash2);
if(hash1.equalsIgnoreCase(hash2))
System.out.println("Both hash Matches..");
else
System.out.println("Hash matches fails..");
}
}
输出:
8WgbLik5EbdtJY4OWm2ZQ0tHiU2lmvXNVrPhFDz3W2Y=
8WgbLik5EbdtJY4OWm2ZQ0tHiU2lmvXNVrPhFDz3W2Y=
Both hash Matches..