gpt4 book ai didi

java SecretKeyFactory 密码哈希无法正常工作

转载 作者:行者123 更新时间:2023-11-30 04:45:57 25 4
gpt4 key购买 nike

我有一个 Web 应用程序,我想将密码哈希存储在远程数据库中。我编写了一个简单的类,它生成密码哈希。有两种公共(public)方法可用:1. 加密 - 加密密码并创建哈希2. checkPassword - 调用 encrypt 创建哈希,然后比较两个哈希

我做了一个简单的测试,进行了两次密码检查,一个应该通过,另一个不应该。

有时有效,有时无效。

正确输出:

password: abcdefg, hash: fd9927e15150bd01713115a761d1dea18b7da4aa
password: abcdefg, salt: 3595ac1baff6aa5e0097520593c7ac74
password: abcdefg, hash: fd9927e15150bd01713115a761d1dea18b7da4aa
password: abcdefg, salt: 3595ac1baff6aa5e0097520593c7ac74
passwords: abcdefg and abcdefg matched: true
password: abcdefgh, hash: a64a2958f3999d8ecdeb03326a151e786435ea4
password: abcdefgh, salt: 3595ac1baff6aa5e0097520593c7ac74
passwords: abcdefg and abcdefgh matched: false

输出错误:

password: abcdefg, hash: 4913fe5cdea3346690463f76f73c1336ae976674
password: abcdefg, salt: 8e2aa1ec28d84fbaf78a6df260a7c707
password: abcdefg, hash: 97abd26927bf96076019b932bf6ab5494a8b0979
password: abcdefg, salt: 8e2aa1ec28d84fbaf78a6df260a7c707
passwords: abcdefg and abcdefg matched: false
password: abcdefgh, hash: 70594cd854bd60e07dfe14f72f01aa1f50de9aa2
password: abcdefgh, salt: 8e2aa1ec28d84fbaf78a6df260a7c707
passwords: abcdefg and abcdefgh matched: false

来源:

import java.math.BigInteger;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Random;

import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;

public class CryptoUtils {

/***************************************************************************
* @param password
*
* @return String[2] { hashed password, salt }
*
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
***************************************************************************/
public static String[] encrypt(String password) throws NoSuchAlgorithmException, InvalidKeySpecException {
byte[] salt = new byte[16];
new Random().nextBytes(salt);

return encrypt(password, salt);
}

private static String[] encrypt(String password, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException {
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 2048, 160);
SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
byte[] hash = f.generateSecret(spec).getEncoded();

String passHash = new BigInteger(1, hash).toString(16);
String saltString = new BigInteger(1, salt).toString(16);

System.out.println("password: " + password + ", hash: " + passHash);// DEBUG
System.out.println("password: " + password + ", salt: " + saltString);

return new String[] { passHash, saltString };
}

public static boolean checkPassword(String password, String hash, String salt) throws NoSuchAlgorithmException, InvalidKeySpecException {
String[] encrypted = encrypt(password, new BigInteger(salt, 16).toByteArray());

return encrypted[0].equals(hash);
}

public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException {
String pass1 = "abcdefg";
String pass2 = pass1;
String pass3 = pass1 + "h";

String[] result = encrypt(pass1);
String hash = result[0];
String salt = result[1];

System.out.println("passwords: " + pass1 + " and " + pass2 + " matched: " + checkPassword(pass2, hash, salt));
System.out.println("passwords: " + pass1 + " and " + pass3 + " matched: " + checkPassword(pass3, hash, salt));
}
}

有人可以帮忙吗?

最佳答案

问题是您使用 BigInteger 将盐字符串转换为字节。如果您的盐字符串为负并且不以零开头,则此代码有效。如果您的盐字符串是正数,则 BigInteger.toByteArray() 必须通过在开头添加一个零字节来进行符号扩展,因此它最终的长度为 17 个字节。另外,如果您的 salt 字符串的最高位字节为零,则 BigInteger.toByteArray() 不需要 16 个字节来表示它,因此您的 salt 最终会出现错误的长度。您可能可以编写逻辑来重新格式化 BigInteger 的输出,使其始终包含 16 个字节,但是一次简单地解析输入字符串两个字符,自行将字节值添加到数组中可能会更容易。

关于java SecretKeyFactory 密码哈希无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10947694/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com