Невозможно проверить passwordhash+salt, созданный с помощью php password_hash() с помощью jBcrypt
Мы переносим наш модуль аутентификации с PHP на Java. В настоящее время пароль хэш + соль хранится в базе данных с использованием алгоритма BCrypt. Это значение генерируется с помощью PHP-функции password_hash(). Для проверки обычного текстового пароля мы используем функцию PHP password_verify().
Код PHP
$hash = password_hash($password,PASSWORD_DEFAULT); //stored in db
if(password_verify($candidate,$hash)===TRUE) { //$hash fetched from DB
echo "valid";
}
Для переноса этого модуля авторизации на Java мы используем библиотеку jBCrypt с помощью jBCrypt-0.4.jar
Java-код
private static String hashPassword(String password) {
String hashed = BCrypt.hashpw(password, BCrypt.gensalt());
return hashed;
}
private static boolean checkpasword(String candidate, String hashed){
boolean matches = false;
if (BCrypt.checkpw(candidate, hashed)){
matches = true;
}
return matches;
}
Тем не менее, пароль хэш + соль, сгенерированный из php, не проверяется в Java. Для строки 'abcd' сгенерированный хеш + соль
PHP - $2y$10$SA4iLMAniuNO6p9P1ZJElePaJvlN5eHGZ2dDt2Mutle4FQr1OY4hC
Java - $2a$10$YnqJT5NPCPTI8qKBbLfgIOIOW4eckdbE1R85tJGNRUJKmxz1TLkWG
Когда я попытался сопоставить строку, сгенерированную с помощью PHP в Java, используя
if (BCrypt.checkpw("abcd", "$2y$10$SA4iLMAniuNO6p9P1ZJElePaJvlN5eHGZ2dDt2Mutle4FQr1OY4hC")){
matches = true;
}
Я получал ниже
Исключение в потоке "main" java.lang.IllegalArgumentException: недопустимая ревизия соли в org.mindrot.jbcrypt.BCrypt.hashpw(BCrypt.java:665) в org.mindrot.jbcrypt.BCrypt.checkpw(BCrypt.java:764)...`
Как мне сделать оба совместимых?
1 ответ
Хеш, сгенерированный password_hash()
в PHP входит соль. Это означает, что когда вы проверяете его по простому текстовому паролю, то же самое соль используется для генерации хеша по простому текстовому паролю, и эти два хеша сравниваются в постоянном времени для проверки.
То, что вы делаете в Java, каждый раз генерирует различную соль, что означает, что вы не можете сравнить их. Ваша реализация Java использует другую версию, обозначенную $2a$
в твоем хеше Обратите внимание, что PHP использует $2y$
и соли явно разные.
Поддерживаются только версии PHP до 5.3.7 "
$2a$
"как солевой префикс: PHP 5.3.7 представил новые префиксы для исправления уязвимости безопасности в реализации Blowfish. Пожалуйста, обратитесь к " этому документу для получения полной информации об исправлении безопасности, но, чтобы подвести итог, разработчики нацелены только на PHP 5.3.7 и позже следует использовать$2y$
"в предпочтении"$2a$
".
Поэтому вам не следует создавать новый хеш в Java для проверки существующего хеша, который был сгенерирован PHP и сохранен в вашей базе данных. Вместо этого предоставьте сохраненный хеш BCrypt.checkpasword
для проверки.