Si te encuentras con algún detalle que te causa duda puedes dejarlo en los comentarios y te ayudaremos tan rápido como podamos.
Solución:
public static void main(String[] args)
// spring 4.0.0
org.springframework.security.crypto.password.PasswordEncoder encoder
= new org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder();
// $2a$10$lB6/PKg2/JC4XgdMDXyjs.dLC9jFNAuuNbFkL9udcXe/EBjxSyqxW
// true
// $2a$10$KbQiHKTa1WIsQFTQWQKCiujoTJJB7MCMSaSgG/imVkKRicMPwgN5i
// true
// $2a$10$5WfW4uxVb4SIdzcTJI9U7eU4ZwaocrvP.2CKkWJkBDKz1dmCh50J2
// true
// $2a$10$0wR/6uaPxU7kGyUIsx/JS.krbAA9429fwsuCyTlEFJG54HgdR10nK
// true
// $2a$10$gfmnyiTlf8MDmwG7oqKJG.W8rrag8jt6dNW.31ukgr0.quwGujUuO
// true
for (int i = 0; i < 5; i++)
// "123456" - plain text - user input from user interface
String passwd = encoder.encode("123456");
// passwd - password from database
System.out.println(passwd); // print hash
// true for all 5 iteration
System.out.println(encoder.matches("123456", passwd));
Las contraseñas generadas son saladas y, por lo tanto, diferentes.
Lea la documentación del método encode() donde se indica claramente que la contraseña está salteada.
Los 22 caracteres directamente después del segundo $ representan el valor de sal, consulte https://en.wikipedia.org/wiki/Bcrypt#Description. "Sal" son algunos datos aleatorios agregados a la contraseña antes del hash, por lo que un algoritmo hash dado con parámetros dados en la mayoría de los casos producirá diferentes valores hash para la misma contraseña (protección contra los llamados ataques arcoíris).
Analicemos el primer resultado que se muestra en la pregunta original:
$2a$10$cYLM.qoXpeAzcZhJ3oXRLu9Slkb61LHyWW5qJ4QKvHEMhaxZ5qCPi
$2a
: Identificador del algoritmo BCrypt$10
: Parámetro para el número de rondas, aquí 2^10 rondascYLM.qoXpeAzcZhJ3oXRLu
: Sal (128 bits)9Slkb61LHyWW5qJ4QKvHEMhaxZ5qCPi
: valor hash real (184 bits)
Tanto la sal como el valor hash se codifican con Radix-64.