使用salt使用密码散列的问题

时间:2016-12-13 09:03:15

标签: java mysql hash salt

这是我第一次在Web应用程序中处理密码散列。 我使用https://www.codeproject.com/articles/704865/salted-password-hashing-doing-it-right作为理论并从https://github.com/defuse/password-hashing复制了一个样本。 根据我的理解,每个帐户的盐应该是唯一的。所以我的问题是:

为什么在这种方法中产生盐:

 public static String createHash(char[] password)
    throws CannotPerformOperationException
{
    // Generate a random salt
    SecureRandom random = new SecureRandom();
    byte[] salt = new byte[SALT_BYTE_SIZE];
    random.nextBytes(salt);

    // Hash the password
    byte[] hash = pbkdf2(password, salt, PBKDF2_ITERATIONS, HASH_BYTE_SIZE);
    int hashSize = hash.length;

    // format: algorithm:iterations:hashSize:salt:hash
    String parts = "sha1:" +
        PBKDF2_ITERATIONS +
        ":" + hashSize +
        ":" +
        toBase64(salt) +
        ":" +
        toBase64(hash);
    return parts;
}

我需要的是一个存储哈希密码和数据库中使用的盐的函数。如何从这里检索用过的盐?

System.out.println(salt);

始终写

[B@29453f44

在控制台中。为什么会这样?我需要将哪种数据类型存储在mysql数据库中?或者我的方法是否错误?

1 个答案:

答案 0 :(得分:0)

如果我理解你的问题,那么:

  

根据我的理解,每个帐户的盐应该是唯一的。

byte[] salt = new byte[SALT_BYTE_SIZE];
random.nextBytes(salt);

生成随机盐,使其独一无二。 您也可以使用ID从数据库或其他独特的用户,但随机生成的盐也是唯一的,因为毕竟,为每个新用户随机生成一个新的盐。

然后,您的代码中的salthashhashSize,算法以及iterations的数量parts连接在一起

 // format: algorithm:iterations:hashSize:salt:hash
String parts = "sha1:" +
    PBKDF2_ITERATIONS +
    ":" + hashSize +
    ":" +
    toBase64(salt) +
    ":" +
    toBase64(hash);
return parts;

通常你知道parts中不同部分的长度(字节大小),因此可以提取你需要的部分。在您的情况下,您甚至添加了:作为分隔符,这使得提取您感兴趣的部分变得更加简单。

  

我需要将哪种数据类型存储在mysql数据库中?

获得parts后,这就是您在数据库中以文字(varcharchar)保存的内容。您不要将其分开并单独存储salt。把它们混合在一起吧。

当用户想要登录时,他们会提供密码。现在,您从数据库中为用户提取parts,从salt中提取iterationsparts的数量,依此类推,因为毕竟,您确切知道它是怎么回事级联。然后,您使用该信息再次对用户输入的密码进行哈希处理。现在,您将新哈希与旧哈希进行比较。如果它们是相同的,那么用户给出了正确的密码,如果没有,他就没有。

  

始终在控制台中写[B@29453f44

正如@JonSkeet所说,答案在Converting String to Sha-256 Hash

中给出