gpt4 book ai didi

java - 散列漏洞

转载 作者:行者123 更新时间:2023-11-30 07:43:03 24 4
gpt4 key购买 nike

我想为我的项目增加一些安全性,所以我添加了一个密码字段。在,为了存储密码,我打算使用一个 txt 并将其保存在那里,为了增加一点安全性,我使用下面的代码来散列密码(如果这很重要,他们的不止一个密码以这种方式保存)。这只是我如何进行散列的示例,实际程序使用文本文件等。

public static void main(String[] args) throws NoSuchAlgorithmException {

System.out.println("Enter Password: ");
Scanner scanner = new Scanner(System.in);
String enteredPassword = scanner.nextLine();
String storedPassword = "�D�Ϛ-�UK�c�=�,�}��}��D��Zj>�m";

MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.update(enteredPassword.getBytes());
String hashedString = new String(messageDigest.digest());
System.out.println(hashedString);

if(storedPassword.equals(hashedString)){
System.out.println("Passwords Match!");
}else{
System.out.println("Passwords Do Not Match!");
}
}

我的问题是,除了反编译我的项目并绕过此功能之外,我这样做是否安全?我的项目是否安全,或者此方法是否可以被利用?另外,有没有办法保护项目不被反编译和重写代码以绕过安全功能?谢谢你

最佳答案

方法本身很好; SHA-256 本身就是一种强大的单向散列函数。它不能被“解密”。但速度很快,因此可以使用字典快速暴力破解密码。

为了更好的安全性,您可以使用例如bcrypt 或 PBKDF2。大约 100 毫秒不会被用户注意到,但这使得暴力破解变得不切实际。

这是一个使用 SHA-256 的 100000 次迭代的 PBKDF2 示例。它还使用随机盐。

SecureRandom random = SecureRandom.getInstanceStrong();
byte[] salt = new byte[16];
random.nextBytes(salt);
KeySpec spec = new PBEKeySpec("my-secret-password".toCharArray(), salt, 100000, 256);
SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
byte[] hash = f.generateSecret(spec).getEncoded();
Base64.Encoder enc = Base64.getEncoder();
System.out.printf("salt: %s%n", enc.encodeToString(salt));
System.out.printf("hash: %s%n", enc.encodeToString(hash));

注意:PBKDF2WithHmacSHA256 从 Java 8 开始可用。


这是一个更完整的例子:

private static final SecureRandom random = new SecureRandom();

/**
* One-way encrypts (hashes) the given password.
*
* @param saltpw the salt (will be generated when null)
* @param pw the password to encrypt
* @return encrypted salted password
*/
public static String encrypt(String saltpw, String pw) throws GeneralSecurityException {
byte[] salt;
if (saltpw == null) {
salt = new byte[16];
random.nextBytes(salt);
} else {
salt = Base64.getDecoder().decode(saltpw.replaceFirst("\\$.*", ""));
}
KeySpec spec = new PBEKeySpec(pw.toCharArray(), salt, 100000, 256);
SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
byte[] hash = f.generateSecret(spec).getEncoded();
Base64.Encoder enc = Base64.getEncoder();
return enc.encodeToString(salt) + "$" + enc.encodeToString(hash);
}

public static void main(String[] args) throws Exception {
String enc = encrypt(null, "my-secret-password");
System.out.printf("enc : %s\n", enc);
String test1 = encrypt(enc, "my-secret-password");
System.out.printf("test 1: %s, valid: %b\n", test1, enc.equals(test1));
String test2 = encrypt(enc, "some-other-password");
System.out.printf("test 2: %s, valid: %b\n", test2, enc.equals(test2));
}

打印:

enc   : B5V6SjkjJpeOxvMAkPf7EA==$NNDA7o+Dpd+M+H99WVxY0B8adqVWJHZ+HIjgPxMljwo=
test 1: B5V6SjkjJpeOxvMAkPf7EA==$NNDA7o+Dpd+M+H99WVxY0B8adqVWJHZ+HIjgPxMljwo=, valid: true
test 2: B5V6SjkjJpeOxvMAkPf7EA==$4H1SpH8N+/jqU40G6RWb+ReHUB3C58iAaU4l39j+TV8=, valid: false

请注意 test 1 如何生成与原始密码完全相同的加密字符串,而 test 2(密码错误)却不会。这就是您可以通过比较哈希来验证提供的密码是否有效的方法。

关于java - 散列漏洞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53833711/

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