Java 比较用盐散列的两个值
我想知道如何比较用盐散列的两个值。 我试过了,但结果总是不一样 请帮忙。提前谢谢 这是我捕获的输出之一Java 比较用盐散列的两个值,java,Java,我想知道如何比较用盐散列的两个值。 我试过了,但结果总是不一样 请帮忙。提前谢谢 这是我捕获的输出之一 hash with salt of String a:OÌÛ _Uùá|.•ðP2š hash with salt of String b:&͸p40”fôŽéž4\õ Not Same 这是我的实现 import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import ja
hash with salt of String a:OÌÛ
_Uùá|.•ðP2š
hash with salt of String b:&͸p40”fôŽéž4\õ
Not Same
这是我的实现
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Arrays;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
public class Test {
public static void main(String[] args) {
String inputOne = "abc";
String a = new String(toHash(inputOne));
System.out.println("hash with salt of String a:" + a);
String inputTwo = "abc";
String b = new String(toHash(inputTwo));
System.out.println("hash with salt of String b:" + b);
if(Arrays.equals(toHash(inputOne), toHash(inputTwo))) {
System.out.println("Same");
}
else {
System.out.println("Not Same");
}
}
public static byte[] toHash(String password) {
byte[] salt = new byte[16];
byte[] hash = null;
SecretKeyFactory f = null;
SecureRandom random = new SecureRandom();
random.nextBytes(salt);
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 128);
try {
f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
hash = f.generateSecret(spec).getEncoded();
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return hash;
}
}
使用salt的原因是,对于同一个明文,您可以获得不同的散列值。那你为什么要用盐呢?这很简单。假设您将哈希密码存储在数据库中。现在,一个黑客来入侵你的数据库。虽然他/她无法以明文形式查看密码,但相同的密码会映射到相同的哈希上。因此,如果20%的哈希值相同,并且您只能解密其中一个密码,那么您就解密了20%的密码数据库。这甚至变得更糟,因为它们是一种东西 要了解有关散列、salt和存储密码的更多信息,您可能需要看一看。问题是SecureRandom=new SecureRandom;random.nextBytessalt nextBytes的文档说明: /** *生成用户指定数量的随机字节。 * *如果之前没有调用setSeed, *对此方法的第一次调用强制此SecureRandom对象 *播种自己。如果 *setSeed以前被称为。 * *@param bytes要用随机字节填充的数组。 */ 如果使用相同的种子调用nextBytes一次,那么它将生成相同的哈希,代码如下:
public class Test {
static SecureRandom random = new SecureRandom();
static byte[] salt = new byte[16];
static {
random.nextBytes(salt);
}
public static void main(String[] args) {
String inputOne = "abc";
String a = new String(toHash(inputOne));
System.out.println("hash with salt of String a:" + a);
String inputTwo = "abc";
String b = new String(toHash(inputTwo));
System.out.println("hash with salt of String b:" + b);
if(Arrays.equals(toHash(inputOne), toHash(inputTwo))) {
System.out.println("Same");
}
else {
System.out.println("Not Same");
}
}
public static byte[] toHash(String password) {
byte[] hash = null;
SecretKeyFactory f = null;
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 128);
try {
f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
hash = f.generateSecret(spec).getEncoded();
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return hash;
}
}
和输出:
用字符串a:D??I?/?的盐进行散列
?*
用字符串b:D??I?/??的盐进行散列
?*
同样的
很明显,只有每次使用相同的盐,它们才会相等。如果您使用随机salt,它将不起作用。干净的方法是存储与用户名或帐户或类似内容关联的salt,然后在输入明文时从中检索它,明文必须与用户名或其他内容关联。但提供的总体方案是正确的。是的,我同意。上面的答案有助于理解如何解决问题,他必须决定最好的方法@请你解释一下,你为什么投了否决票?
public class Test {
static SecureRandom random = new SecureRandom();
static byte[] salt = new byte[16];
static {
random.nextBytes(salt);
}
public static void main(String[] args) {
String inputOne = "abc";
String a = new String(toHash(inputOne));
System.out.println("hash with salt of String a:" + a);
String inputTwo = "abc";
String b = new String(toHash(inputTwo));
System.out.println("hash with salt of String b:" + b);
if(Arrays.equals(toHash(inputOne), toHash(inputTwo))) {
System.out.println("Same");
}
else {
System.out.println("Not Same");
}
}
public static byte[] toHash(String password) {
byte[] hash = null;
SecretKeyFactory f = null;
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 128);
try {
f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
hash = f.generateSecret(spec).getEncoded();
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return hash;
}
}