Мы переносим наш модуль аутентификации с 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)
at org.mindrot.jbcrypt.BCrypt.checkpw (BCrypt.java:764) … `
Как мне сделать оба совместимых?
Хеш, сгенерированный 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
для проверки.
Других решений пока нет …