java - encrypt - spring security password encoder
Cómo usar el nuevo PasswordEncoder de Spring Security (4)
A partir de Spring Security 3.1.4.RELEASE, el antiguo org.springframework.security.authentication.encoding.PasswordEncoder
ha quedado en desuso en favor de org.springframework.security.crypto.password.PasswordEncoder
. Como mi aplicación aún no se ha lanzado al público, decidí pasar a la API nueva, no obsoleta.
Hasta ahora, tenía un ReflectionSaltSource
que utilizaba automáticamente la fecha de registro del usuario como contraseña por usuario para la contraseña.
String encodedPassword = passwordEncoder.encodePassword(rawPassword, saltSource.getSalt(user));
Durante el proceso de inicio de sesión, Spring también usó mis beans para verificar si el usuario puede o no iniciar sesión. No puedo lograr esto en el nuevo codificador de contraseñas, porque la implementación predeterminada de SHA-1 - StandardPasswordEncoder
solo tiene la capacidad de agregar un sal secreta global durante la creación del codificador.
¿Hay algún método razonable de cómo configurarlo con la API no obsoleta?
Aquí está la implementación de BCrypt que funciona para mí.
en spring-security.xml
<authentication-manager >
<authentication-provider ref="authProvider"></authentication-provider>
</authentication-manager>
<beans:bean id="authProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="userDetailsServiceImpl" />
<beans:property name="passwordEncoder" ref="encoder" />
</beans:bean>
<!-- For hashing and salting user passwords -->
<beans:bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
En la clase java
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String hashedPassword = passwordEncoder.encode(yourpassword);
Para un ejemplo más detallado de seguridad de primavera, haga clic aquí
Espero que esto ayude
Gracias
Después de haber recorrido Internet para leer sobre esto y las opciones en Spring, respondí en segundo lugar a Luke, use BCrypt (se menciona en el código fuente en Spring).
El mejor recurso que encontré para explicar por qué usar hash / salt y por qué usar BCrypt es una buena opción aquí: hashing de contraseña salada: hacerlo bien .
Si en realidad no ha registrado ningún usuario con su formato existente, sería mejor que cambie al uso del codificador de contraseña BCrypt .
Es mucho menos complicado, ya que no tiene que preocuparse por la sal en absoluto: los detalles están completamente encapsulados dentro del codificador. Usar BCrypt es más fuerte que usar un algoritmo hash simple y también es un estándar que es compatible con aplicaciones que usan otros lenguajes.
Realmente no hay razón para elegir alguna de las otras opciones para una nueva aplicación.
Tuve un problema similar. Necesitaba mantener las contraseñas encriptadas heredadas ( Base64 / SHA-1 / Sal aleatoria codificada ) ya que los usuarios no querrán cambiar sus contraseñas o volver a registrarse. Sin embargo, también quería usar el codificador BCrypt para avanzar.
Mi solución fue escribir un decodificador hecho a medida que verificara qué método de encriptación se usó primero antes de la coincidencia (los cifrados comienzan con $
).
Para evitar el problema de la sal, paso al decodificador una cadena de sal concatenada + contraseña encriptada a través de mi objeto de usuario modificado.
Descifrador
@Component
public class LegacyEncoder implements PasswordEncoder {
private static final String BCRYP_TYPE = "$";
private static final PasswordEncoder BCRYPT = new BCryptPasswordEncoder();
@Override
public String encode(CharSequence rawPassword) {
return BCRYPT.encode(rawPassword);
}
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
if (encodedPassword.startsWith(BCRYP_TYPE)) {
return BCRYPT.matches(rawPassword, encodedPassword);
}
return sha1SaltMatch(rawPassword, encodedPassword);
}
@SneakyThrows
private boolean sha1SaltMatch(CharSequence rawPassword, String encodedPassword) {
String[] saltHash = encodedPassword.split(User.SPLIT_CHAR);
// Legacy code from old system
byte[] b64salt = Base64.getDecoder().decode(saltHash[0].getBytes());
byte[] validHash = Base64.getDecoder().decode(saltHash[1]);
byte[] checkHash = Utility.getHash(5, rawPassword.toString(), b64salt);
return Arrays.equals(checkHash, validHash);
}
}
Objeto de usuario
public class User implements UserDetails {
public static final String SPLIT_CHAR = ":";
@Id
@Column(name = "user_id", nullable = false)
private Integer userId;
@Column(nullable = false, length = 60)
private String password;
@Column(nullable = true, length = 32)
private String salt;
.
.
@PostLoad
private void init() {
username = emailAddress; //To comply with UserDetails
password = salt == null ? password : salt + SPLIT_CHAR + password;
}
También puede agregar un gancho para volver a codificar la contraseña en el nuevo formato de BCrypt y reemplazarlo. Por lo tanto, eliminando gradualmente el método anterior.