パスワードフィールド、入力ボタン、および入力領域を持つ簡単なGUIを作成して、ボタンを押したときに生成されたパスワードのハッシュを表示しました。しかし、ボタンをもう一度押すと、入力パスワードが変わってもハッシュが変わります。毎回出力ハッシュが変更されるので、入力パスワードと保存されたパスワードを比較することはできません。ここでHMAC SHA1を使用したJavaのPBKDF2の実装では、ボタンを押すたびに異なるハッシュが返されますか?
はコードです:
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メソッドから呼び出す場合にのみ、同じハッシュを毎回返します。何故ですか?同じパスワードを入力してボタンを押すたびに同じ値を返すようにするにはどうすればいいですか?
私は文字列を前後に隠すときに問題を見つけ出すと思います。メソッドhashPasswordをhashPassword(char [] password、String salt)に編集し、今すぐ動作させました。
文字列を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は、「パスワード」.toCharArray()が等しいので、それは非常に奇妙です。 String.toCharArray()にバグがあるのだろうか?
塩漬けハッシュ、定義によって、毎回異なっています。なぜあなたはそれらが同じであると思いますか?これがあなたの望むものなら、毎回同じ塩を食べてください。しかし、生産中にはしないでください。 – fge
@fgeの場合、同じsaltは同じハッシュ値を返さなければなりません。 –
まず、問題を単純化して、mainメソッドからの固定値で 'hashPassword'メソッドを呼び出してテストし、出力をSystem.outに出力してください。 –