Получение разных хеш-значений одного и того же пароля (+ соль) - PullRequest
0 голосов
/ 07 декабря 2018

Я пытался получить хешированный пароль, следуя приведенному здесь коду . Из него я сейчас использую только код для метода salt, метод hashи isExpectedPassword метод.

Я получаю свой пароль из текстового поля:

char[] passCharArray = txtPassword.toString().toCharArray();

Затем я вызываю класс, чтобы получить солт-значение (я называю его Encryptor вместо Passwords как в оригинальном сообщении):

byte[] salt = Encryptor.getNextSalt();

И затем я получаю хешированный пароль:

byte[] hashedPass = Encryptor.hash(passCharArray, salt);

Используя следующий код, я печатаю результаты, чтобы увидеть, что происходит, иРезультаты прокомментированы:

String saltString = Arrays.toString(salt);
System.out.println("SALT: " + saltString);
//SALT: [18, 117, -98, 41, 92, 124, 118, 17, 107, 14, 0, -81, 110, 70, 10, 42]

String hashedPassString = Arrays.toString(hashedPass);
System.out.println("HASHED PASS: " + hashedPassString);
//HASHED PASS: [44, -127, -43, 84, 40, -16, -46, -71, 109, -44, -41, 47, -61, -119, 21, 99, -23, 101, -13, 116, -12, 118, -66, 44, 104, 5, 4, 18, -55, 47, 59, 116]

System.out.println("Passwords match: " + Encryptor.isExpectedPassword(passCharArray, salt, hashedPass));
//Passwords match: false

Ниже приведены два значения System.out.print, которые я вставил в метод isExpectedPassword, чтобы увидеть, какие значения получаются при вызове.

//Encryptor pwdHash: [-103, -87, 53, -75, 59, 11, 77, 116, 123, 59, 68, -35, 16, -68, 42, 34, -32, 75, 22, -94, -37, -26, 16, 20, 7, -46, -6, -20, -88, 104, -121, 77]
//Encryptor expectedHash: [44, -127, -43, 84, 40, -16, -46, -71, 109, -44, -41, 47, -61, -119, 21, 99, -23, 101, -13, 116, -12, 118, -66, 44, 104, 5, 4, 18, -55, 47, 59, 116]

В общем, hashedPassexpectedHash) должны совпадать с pwdHash, но это не так.Я не понимаю, что я делаю не так.Я что-то упустил в своем коде?Что-то меняется без моего ведома?

Это мой полный код, если люди хотят увидеть все это на всякий случай:

public class Encryptor {

    private static final Random RANDOM = new SecureRandom();
    private static final int ITERATIONS = 10000;
    private static final int KEY_LENGTH = 256;

    private Encryptor(){}

    public static byte[] getNextSalt(){
        byte[] salt = new byte[16];
        RANDOM.nextBytes(salt);
        return salt;
    }

    public static byte[] hash(char[] password, byte[] salt) {
        PBEKeySpec spec = new PBEKeySpec(password, salt, ITERATIONS, KEY_LENGTH);
        Arrays.fill(password, Character.MIN_VALUE);
        try {
            SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
            return skf.generateSecret(spec).getEncoded();
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            throw new AssertionError("Error while hashing a password: " + e.getMessage(), e);
        } finally {
            spec.clearPassword();
        }
    }

    public static boolean isExpectedPassword(char[] password, byte[] salt, byte[] expectedHash) {
        byte[] pwdHash = hash(password, salt);

        String s = Arrays.toString(pwdHash);
        System.out.println("Encryptor pwdHash: " + s);

        String s2 = Arrays.toString(expectedHash);
        System.out.println("Encryptor expectedHash: " + s2);

        Arrays.fill(password, Character.MIN_VALUE);
        if (pwdHash.length != expectedHash.length) return false;
        for (int i = 0; i < pwdHash.length; i++) {
            if (pwdHash[i] != expectedHash[i]) return false;
        }
        return true;
    }


}


public class Controller implements Initializable {
    @FXML
    private Button btnLogin;
    //Some private variables

    @FXML
    private AnchorPane ancPane;
    @FXML
    private ImageView imgLogo;
    @FXML
    private Hyperlink hplRegister;
    @FXML
    private TextField txtUsername;
    @FXML
    private TextField txtPassword;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        //Some styling

        hplRegister.setOnAction(event -> {
            //Registering event
        });

        btnLogin.setOnAction(event -> {
            try {

                //Loading fxml data
                // I've put the code here just for testing purposes
                // and will not be the final placement.

                char[] passCharArray = txtPassword.toString().toCharArray();

                byte[] salt = Encryptor.getNextSalt();
                byte[] hashedPass = Encryptor.hash(passCharArray, salt);

                String saltString = Arrays.toString(salt);
                System.out.println("SALT: " + saltString);

                String hashedPassString = Arrays.toString(hashedPass);
                System.out.println("HASHED PASS: " + hashedPassString);

                System.out.println("Passwords match: " + Encryptor.isExpectedPassword(passCharArray, salt, hashedPass));

            }catch (Exception e){
                e.printStackTrace();
            }
        });
    }

    //Some getter methods.
}

1 Ответ

0 голосов
/ 07 декабря 2018

Проблема в том, что вы стираете пароль.когда вы хэшируете пароль, вы стираете массив символов, заполняйте его пробелами, это очищает passCharArray.Когда вы передаете его во второй раз, он в основном проверяет хэш пароля по сравнению с хешем пустого массива.и те точно не совпадают.

В реальном случае вы получите соль и хешированный пароль из БД или другого источника.Входящая версия не будет хеширована и, следовательно, очищена, пока не будет передана в isExpectedPassword

...