比较使用salt

时间:2015-07-11 15:39:31

标签: java

我想知道如何比较两个哈希值的哈希值。 我试过但它一直给我输出" 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;
    }
}

2 个答案:

答案 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