У меня есть вариант использования в моем приложении, который должен помешать пользователю выбрать один из последних 3 паролей при сбросе пароля. Я использую Angular для интерфейса и Spring Boot для сервера. В моем сценарии пароли пользователей хранятся в виде хэша bcrypt.
Как я могу сравнить пароль, введенный пользователем, с последними 3 сохраненными паролями bcrypt?
Когда я запускаю следующий пример фрагмента кода,
BCryptPasswordEncoder b = new BCryptPasswordEncoder();
for(int i =0;i<10;i++) {
System.out.println(b.encode("passw0rd"));
}
он генерирует следующие хэши bcrypt. каждый хеш отличается, что разумно, потому что, когда я проверяю org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder, я вижу, что сгенерированная соль является случайным значением.
$2a$10$tztZsPFZ.T.82Gl/VIuMt.RDjayTwuMLAkRkO9SB.rd92vHWKZmRm
$2a$10$yTHyWDmcCBq3OSPOxjj4TuW9qXYE31CU.fFlWxppii9AizL0lKMzO
$2a$10$Z6aVwg.FNq/2I4zmDjDOceT9ha0Ur/UKsCfdADLvNHiZpR7Sz53fC
$2a$10$yKDVeOUvfTQuTnCHGJp.LeURFcXK6JcHB6lrSgoX1pRjxXDoc8up.
$2a$10$ZuAL06GS7shHz.U/ywb2iuhv2Spubl7Xo4NZ7QOYw3cHWK7/7ZKcC
$2a$10$4T37YehBTmPWuN9j.ga2XeF9GHy6EWDhQS5Uc9bHvJTK8.xIm1coS
$2a$10$o/zxjGkArT7YdDkrk5Qer.oJbZAYpJW39iWAWFqbOhpTf3FmyfWRC
$2a$10$eo7yuuE2f7XqJL8Wjyz.F.xj78ltWuMS1P0O/I6X7iNPwdsWMVzu6
$2a$10$3ErH2GtZpYJGg1BhfgcO/uOt/L2wYg4RoO8.fNRam458WWdymdQLW
$2a$10$IksOJvL/a0ebl4R2/nbMQ.XmjNARIzNo8.aLXiTFs1Pxd06SsnOWa
Конфигурация безопасности Spring.
@Configuration
@Import(SecurityProblemSupport.class)
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@PostConstruct
public void init() {
try {
authenticationManagerBuilder
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
} catch (Exception e) {
throw new BeanInitializationException("Security configuration failed", e);
}
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
На самом деле я нашел свой ответ.
Я понял, что могу использовать функцию matches в классе org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder.
System.out.println(b.matches("passw0rd", "$2a$10$tztZsPFZ.T.82Gl/VIuMt.RDjayTwuMLAkRkO9SB.rd92vHWKZmRm"));
вы можете использовать метод matches в BCryptPasswordEncoder, примерно так:
b.matches("passw0rd", hash)
Это решение. Можете ли вы помочь мне понять, как Spring Security соответствует хеш-паролю, хранящемуся в базе данных, и текстовому паролю, который, конечно же, задается пользователем, который будет другим хэшем после кодирования !!!???
Spring Security просто считывает соль из ранее сгенерированного хэша и снова перефразирует входной пароль с той же солью. И он сравнивает оба окончательных хэша, и, очевидно, они будут одинаковыми.
Пример:
Пароль: test
Хэш: $2a$10$nCgoWdqJwQs9prt7X5a/2eWLn88I8pon6iNat90u4rq4mHqtoPGQy
Хэш состоит из 3 сегментов, разделенных символом $. 2a — это версия Bcrypt, 10 — это общее количество раундов, а nCgoWdqJwQs9prt7X5a/2e — соль.
Таким образом, Spring Security берет пароль test и соль nCgoWdqJwQs9prt7X5a/2e и запускает метод хеширования. Очевидно, он генерирует тот же хэш, что и пароль, и соль.
Это решение. Можете ли вы помочь мне понять, как Spring Security соответствует хеш-паролю, хранящемуся в базе данных, и текстовому паролю, который, конечно же, задается пользователем, который будет другим хэшем после кодирования !!!???