Mejore la seguridad de las contraseñas :3
This commit is contained in:
@@ -1,12 +1,11 @@
|
||||
package xyz.danielcortes.controllers.mantenedores.trabajador.usuario;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import xyz.danielcortes.controllers.LaunchController;
|
||||
import xyz.danielcortes.controllers.mantenedores.trabajador.TrabajadorViewController;
|
||||
import xyz.danielcortes.framework.BaseController;
|
||||
import xyz.danielcortes.framework.BasePanel;
|
||||
import xyz.danielcortes.framework.Hash;
|
||||
import xyz.danielcortes.framework.PanelName;
|
||||
import xyz.danielcortes.framework.Passwords;
|
||||
import xyz.danielcortes.framework.ValidationResult;
|
||||
import xyz.danielcortes.models.Trabajador;
|
||||
import xyz.danielcortes.models.Usuario;
|
||||
@@ -68,7 +67,8 @@ public class UsuarioCreateController extends BaseController {
|
||||
|
||||
Usuario usuario = new Usuario();
|
||||
usuario.setNombre(user);
|
||||
usuario.setPassword(Hash.sha256(new String(pass).getBytes(StandardCharsets.UTF_8)));
|
||||
usuario.setSalt(Passwords.getNextSalt());
|
||||
usuario.setPassword(Passwords.hash(pass, usuario.getSalt()));
|
||||
usuario.setTrabajador(trabajador);
|
||||
|
||||
this.repository.save(usuario);
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
package xyz.danielcortes.controllers.mantenedores.trabajador.usuario;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import xyz.danielcortes.controllers.LaunchController;
|
||||
import xyz.danielcortes.controllers.mantenedores.trabajador.TrabajadorViewController;
|
||||
import xyz.danielcortes.framework.BaseController;
|
||||
import xyz.danielcortes.framework.BasePanel;
|
||||
import xyz.danielcortes.framework.Hash;
|
||||
import xyz.danielcortes.framework.PanelName;
|
||||
import xyz.danielcortes.framework.Passwords;
|
||||
import xyz.danielcortes.framework.ValidationResult;
|
||||
import xyz.danielcortes.models.Trabajador;
|
||||
import xyz.danielcortes.repository.UsuarioRepository;
|
||||
@@ -77,7 +76,8 @@ public class UsuarioUpdateController extends BaseController {
|
||||
}
|
||||
|
||||
trabajador.getUsuario().setNombre(user);
|
||||
trabajador.getUsuario().setPassword(Hash.sha256(new String(pass).getBytes(StandardCharsets.UTF_8)));
|
||||
trabajador.getUsuario().setSalt(Passwords.getNextSalt());
|
||||
trabajador.getUsuario().setPassword(Passwords.hash(pass, trabajador.getUsuario().getSalt()));
|
||||
|
||||
this.repository.update(trabajador.getUsuario());
|
||||
this.volver();
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
package xyz.danielcortes.framework;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Base64;
|
||||
|
||||
public class Hash {
|
||||
|
||||
private static MessageDigest sha;
|
||||
|
||||
static {
|
||||
try {
|
||||
sha = MessageDigest.getInstance("SHA-256");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static String sha256(byte[] toHash) {
|
||||
return Base64.getEncoder().encodeToString(sha.digest(toHash));
|
||||
}
|
||||
}
|
||||
46
src/main/java/xyz/danielcortes/framework/Passwords.java
Normal file
46
src/main/java/xyz/danielcortes/framework/Passwords.java
Normal file
@@ -0,0 +1,46 @@
|
||||
package xyz.danielcortes.framework;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
|
||||
public class Passwords {
|
||||
private static final Random RANDOM = new SecureRandom();
|
||||
private static final int ITERATIONS = 10000;
|
||||
private static final int KEY_LENGHT = 256;
|
||||
|
||||
private Passwords(){}
|
||||
|
||||
public static byte[] getNextSalt() {
|
||||
byte[] salt = new byte[16];
|
||||
RANDOM.nextBytes(salt);
|
||||
return salt;
|
||||
}
|
||||
|
||||
public static byte[] hash(char[] password, byte[] salt){
|
||||
PBEKeySpec spec = new PBEKeySpec(password, salt, ITERATIONS, KEY_LENGHT);
|
||||
Arrays.fill(password, Character.MIN_VALUE);
|
||||
try{
|
||||
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
|
||||
return skf.generateSecret(spec).getEncoded();
|
||||
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
|
||||
throw new AssertionError("Error while hashing a password: " + e.getMessage(), e);
|
||||
} finally {
|
||||
spec.clearPassword();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isExpectedPassword(char[] password, byte[] salt, byte[] expectedHash){
|
||||
byte[] pwdHash = hash(password, salt);
|
||||
Arrays.fill(password, Character.MIN_VALUE);
|
||||
if(pwdHash.length != expectedHash.length) return false;
|
||||
for(int i = 0; i < pwdHash.length; i++){
|
||||
if(pwdHash[i] != expectedHash[i]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,13 @@
|
||||
package xyz.danielcortes.login;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Optional;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.WindowConstants;
|
||||
import xyz.danielcortes.framework.Hash;
|
||||
import xyz.danielcortes.framework.LoggedEvent;
|
||||
import xyz.danielcortes.framework.LoggedListener;
|
||||
import xyz.danielcortes.framework.Passwords;
|
||||
import xyz.danielcortes.models.Usuario;
|
||||
import xyz.danielcortes.repository.UsuarioRepository;
|
||||
|
||||
@@ -46,8 +45,8 @@ public class LoginController {
|
||||
}
|
||||
|
||||
Usuario user = optionalUser.get();
|
||||
String pass = Hash.sha256(new String(this.view.getPassField().getPassword()).getBytes(StandardCharsets.UTF_8));
|
||||
if (pass.equals(user.getPassword())) {
|
||||
char[] pass = this.view.getPassField().getPassword();
|
||||
if (Passwords.isExpectedPassword(pass, user.getSalt(), user.getPassword())) {
|
||||
this.frame.dispose();
|
||||
loggedListener.loginTry(new LoggedEvent(this, user));
|
||||
} else {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package xyz.danielcortes.models;
|
||||
|
||||
import java.util.Objects;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
@@ -21,8 +20,11 @@ public class Usuario {
|
||||
@Column(name = "nombre")
|
||||
private String nombre;
|
||||
|
||||
@Column(name = "password")
|
||||
private String password;
|
||||
@Column(name = "password", columnDefinition = "BINARY(32) NOT NULL")
|
||||
private byte[] password;
|
||||
|
||||
@Column(name = "salt", columnDefinition = "BINARY(16) NOT NULL")
|
||||
private byte[] salt;
|
||||
|
||||
@OneToOne
|
||||
@JoinColumn(name = "trabajador_id", referencedColumnName = "id")
|
||||
@@ -44,14 +46,22 @@ public class Usuario {
|
||||
this.nombre = nombre;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
public byte[] getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
public void setPassword(byte[] password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public byte[] getSalt() {
|
||||
return salt;
|
||||
}
|
||||
|
||||
public void setSalt(byte[] salt) {
|
||||
this.salt = salt;
|
||||
}
|
||||
|
||||
public Trabajador getTrabajador() {
|
||||
return trabajador;
|
||||
}
|
||||
@@ -59,22 +69,4 @@ public class Usuario {
|
||||
public void setTrabajador(Trabajador trabajador) {
|
||||
this.trabajador = trabajador;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (!(o instanceof Usuario))
|
||||
return false;
|
||||
Usuario usuario = (Usuario) o;
|
||||
return Objects.equals(id, usuario.id) &&
|
||||
Objects.equals(nombre, usuario.nombre) &&
|
||||
Objects.equals(password, usuario.password) &&
|
||||
Objects.equals(trabajador, usuario.trabajador);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, nombre, password, trabajador);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user