Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 比较用盐散列的两个值_Java - Fatal编程技术网

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;
    }
}