我想知道如何比较两个哈希值的哈希值。 我试过但它一直给我输出" Not Same"。
请帮忙。提前谢谢。
这是我捕获的输出之一
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;
}
}
答案 0 :(得分:0)
问题是SecureRandom random = new SecureRandom();random.nextBytes(salt);
nextBytes
的文档说:
/ ** *生成用户指定的随机字节数。 * *
如果以前没有发生对
setSeed
的调用, *第一次调用此方法会强制使用此SecureRandom对象 *播种自己。如果,这种自播不会发生 先前已调用setSeed
。 * * @param字节用随机字节填充数组。 * /
synchronized public void nextBytes(byte[] bytes) {
secureRandomSpi.engineNextBytes(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 ??我?/ ????
?*
用字符串b的哈希哈希:D ??我?/ ????
?*
同
答案 1 :(得分:-1)
salt的原因是,对于相同的明文,您会得到不同的哈希值。那你为什么要用盐?这很简单。想象一下,您将散列密码存储在数据库中。现在黑客出现并攻击您的数据库。虽然他/她无法以明文形式查看密码,但相同的密码会映射到相同的哈希值。因此,如果所有哈希值的20%相同且您只能解密其中一个密码,则解密密码数据库的20%。这甚至变得更糟,因为rainbow tables是一件事。
要了解有关散列,加密和存储密码的更多信息,您可能需要查看this computerphile video about the topic。