每次按下按钮时,带有HMAC SHA1的Java PBKDF2实现都会返回不同的哈希值?

卢克·马丁(Luke Martin)

我创建了一个简单的GUI,其中包含一个密码字段,一个Enter按钮和一个文本区域,以在按下Enter按钮时显示生成的密码哈希值。但是,当我再次按下按钮时,即使输入密码仍然相同,哈希也会更改。由于输出哈希值每次都会更改,因此我无法将输入密码与存储的密码进行比较。

这是代码:

import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;

public PBKDF2() {
    initComponents();
}

private void initComponents() {//"Generated Code"
...... 
}

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
    password= jPasswordField1.getPassword();
    jTextArea1.setText(null);
    try {
        jTextArea1.append(hashPassword(password.toString(), "salt"));
    } catch (NoSuchAlgorithmException | InvalidKeySpecException ex) {
        Logger.getLogger(PBKDF2.class.getName()).log(Level.SEVERE, null, ex);
    }
}

public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new PBKDF2().setVisible(true);
            }
        });
    }

 public static String hashPassword(String password, String salt) throws NoSuchAlgorithmException, InvalidKeySpecException{
    char[] pw = password.toCharArray();
    byte[] slt = salt.getBytes(StandardCharsets.UTF_8);
    PBEKeySpec spec = new PBEKeySpec(pw,slt,2000,160);
    SecretKeyFactory key = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
    byte[] hashedPassword = key.generateSecret(spec).getEncoded();
    return String.format("%X", new BigInteger(hashedPassword));
  }

    public static char[] password;
    public javax.swing.JButton jButton1;
    public javax.swing.JPasswordField jPasswordField1;
    public javax.swing.JScrollPane jScrollPane1;
    public javax.swing.JTextArea jTextArea1;
}

如果我从main方法调用它,则每次仅返回相同的哈希值。这是为什么?每当我输入相同的密码并按下按钮时,如何使它返回相同的值?

我认为我发现了来回隐藏字符串到chararray的问题。将方法hashPassword编辑为hashPassword(char []密码,字符串盐),并使它现在可以工作。

以某种方式将String转换为CharArray时,每次输出都是不同的。这是测试代码:

Code:
char[] pw0="password".toCharArray();
char[] pw1="password".toCharArray();

jTextArea1.append("\nCase1: "+hashPassword(pw0.toString(), "salt"));
jTextArea1.append("\nCase2:"+hashPassword(pw1.toString(), "salt"));

Result:        
Case1: -48b7cb730ce85dd46cb2cac6960eb1971f2d30e4
Case2:64765fbdada52d536d89bf2fac72b058397e9ec9

这很奇怪,因为pw0和pw1等于“ password” .toCharArray()。我想知道String.toCharArray()中是否有错误?

奥利维尔·格雷戈尔(OlivierGrégoire)

从技术上讲,您致电

"abc".toCharArray().toString();

这将导致

[C@abcdef10

因此,每次运行时您将获得的价值始终是另一个价值。

您应该做的是:

jTextArea1.append("\nCase1: "+hashPassword(new String(pw0), "salt"));
...

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章