Metodo de criptografar senha c bcrypt

Bom eu estou criptografando minha senha e login ao criar o usuario;

  public  boolean cadastrar(Usuario u, Matricula m) throws SQLException {  
        String geradoLogin = BCrypt.gensalt();
        String geradoSenha = BCrypt.gensalt();
        String senhaCrypt = BCrypt.hashpw(u.getSenha(), geradoSenha);
        String loginCrypt = BCrypt.hashpw(u.getLogin(), geradoLogin);  
        u.setLogin(loginCrypt);
        u.setSenha(senhaCrypt);
        PreparedStatement matricula = con.prepareStatement("INSERT INTO MATRICULA(numero_matricula, numero_computador) VALUES(?, ?)",PreparedStatement.RETURN_GENERATED_KEYS);
        matricula.setInt(1, m.getNumero_matricula());
        matricula.setInt(2, m.getNumero_computador());
        try {
        con.setAutoCommit(false);
        matricula.executeUpdate();
        ResultSet rs = matricula.getGeneratedKeys();
        rs.next();
        Long idGerado = rs.getLong(1);
        Sessao.getInstancia().getMatricula().setId_matricula(idGerado);
        String cadastrarx = "INSERT INTO USUARIO(idpermissao,idmatricula, login, senha, nome,online) VALUES("+u.isAdm()+","+idGerado+",?,?,?,0)";
        PreparedStatement cadastrar = con.prepareStatement(cadastrarx);
        cadastrar.setString(1, u.getLogin());
        cadastrar.setString(2,u.getSenha());
        cadastrar.setString(3,u.getNome());
        cadastrar.executeUpdate();
        con.commit();
        }catch(Exception e){
            Logger.getLogger(UsuarioDAO.class.getName()).log(Level.SEVERE, null, e);
            con.rollback();
            return false;
            } 
            return true;
        }

minha dúvida está em como eu conseguiria fazer a validação quando está sendo feito o login?

   public boolean validarSenha(Usuario u) {
        String sql = "SELECT * FROM usuario where login = ? and senha = ?";
        try {
            PreparedStatement stmt = con.prepareStatement(sql);
            stmt.setString(1, u.getLogin());
            stmt.setString(2, u.getSenha());
            ResultSet rs = stmt.executeQuery();
            if (rs.next()) {             
                Usuario usuarioLogado = new Usuario(rs.getLong("id_usuario"), rs.getInt("idpermissao"), rs.getString("login"), rs.getString("senha"),  rs.getString("nome"), rs.getBoolean("online"));
                Matricula matricula = new Matricula(rs.getLong("idmatricula"));
                aSessao.getInstancia().setUsuario(usuarioLogado);
                aSessao.getInstancia().setMatricula(matricula);  
                setOnline();
                stmt.close();
                rs.close();
                return true;
            }else{
            stmt.close();
            rs.close();
            return false;
            }
        } catch (SQLException ex) {
            Logger.getLogger(UsuarioDAO.class.getName()).log(Level.SEVERE, null, ex);

        }
        return false;
    }

eu criei um metodo para descriptografar
mas ele só serviria para o usuario logado
como conseguir um metodo padrão para utilizar em todos os casos?

Não precisa descriptografar os valores!

Criptografa os valores fornecidos pelo usuário e veja se a criptografia ficou igual a que foi salva, se está igual o usuário e senha estão corretos, se ficou diferente, o usuário ou senha informados não são válidos.

2 curtidas
String geradoLogin = BCrypt.gensalt();
        String geradoSenha = BCrypt.gensalt();
        String senhaCrypt = BCrypt.hashpw(u.getSenha(), geradoSenha);
        String loginCrypt = BCrypt.hashpw(u.getLogin(), geradoLogin);  
        u.setLogin(loginCrypt);
        u.setSenha(senhaCrypt);
        String sql = "SELECT * FROM usuario where login = ? and senha = ?";
        try {
            PreparedStatement stmt = con.prepareStatement(sql);
            stmt.setString(1, u.getLogin());
            stmt.setString(2, u.getSenha());
            ResultSet rs = stmt.executeQuery();

eu tentei isso e a deu senha errada.

Você tem que ter a chave da encriptação do registro, para chaves diferentes, encriptações diferentes, logo, nunca será igual!

não entendi mt bem
poderia me dar um exemplo?
como eu conseguiria essa chave?

Aí tem que entender como a api bcrypt funciona pra poder fazer isso, eu não conheço a mesma pra poder te dar um exemplo!

Mas independente de api, a lógica é a mesma, para encriptar um valor se usa um algoritmo de encriptação e uma chave de encriptação, pois se não temos uma chave de encriptação o valor encriptado nunca mais conseguirá ser desencriptado entende?

Imagino eu que quem está gerando essa chave no seu caso é esse gensalt(), mas não tenho certeza, dá uma olhada na documentação da api e vê o que diz a respeito para que você consiga ajustar o seu código.

eu tinha dado uma lida por isso eu fiz aquilo para descriptografar

// Check that an unencrypted password matches one that has
// previously been hashed
if (BCrypt.checkpw(candidate, hashed))
	System.out.println("It matches");

o metodo gensalt :

	public static String gensalt(int log_rounds, SecureRandom random) {
		StringBuffer rs = new StringBuffer();
		byte rnd[] = new byte[BCRYPT_SALT_LEN];
		random.nextBytes(rnd);
		rs.append("$2a$");
		if (log_rounds < 10)
			rs.append("0");
		if (log_rounds > 30) {
			throw new IllegalArgumentException(
			    "log_rounds exceeds maximum (30)");
		}
		rs.append(Integer.toString(log_rounds));
		rs.append("$");
		rs.append(encode_base64(rnd, rnd.length));
		return rs.toString();
	}

não achei nada sobre isso de chave.

Boa noite!

Apenas usa uma hash, por exemplo md5.
Não precisa descriptografar como @Jonathan_Medeiros já disse, ou seja, o segredo é pegar a senha informada pelo usuário, criptografar e verificar se é igual a que tu tens cadastrada no banco de dados.

OBS.: Isso te dá segurança, caso alguém invada teu sistema, não saberá a senha do usuário do sistema, pois não tem como ela ser descriptografada.

Abraços!

1 curtida

vlw manin
eu dei uma olhada pelo que vi
do jeito que eu estava fazendo com o bcrypt eu não irei poder usar o encrypt no login pois vou utilizar ele no meu select para validação.

Acredito que você não tenha realmente lido, pois em pouco tempo de leitura já consegui identificar aqui o funcionamento da Bcrypt, mas enfim…

Suponha-se que você tenha um usuário cadastrado como (Login: admin, Pass: admin).

Ao chamar o método:

String salt = Bcrypt.gensalt(); //Vai gerar uma chave única de encriptação com 29 caracteres

Com isso você consegue encriptar um valor da seguinte forma:

String pass = "admin";
BCrypt.hashpw(pass, salt); //Vai gerar a encriptação do valor como um todo contendo a chave de encriptação e o valor encriptado

Sabendo disso você vai salvar esse valor encriptado na base de dados, mas como vou saber compará-lo depois, pois bem, você faz uma consulta simples pelo usuário no BD, recupera o pass que foi salvo encriptado anteriormente e faz a seguinte comparação:

if (BCrypt.checkpw(senhaQueUsuarioDigitou, passEncriptadoQueFoiSalvoNoBD)) {
     //Vai retornar true, ou seja, a senha está correta
} else {
    //Vai retornar false, ou seja, a senha digitada não confere
}

O problema é, se você encriptar o usuário e a senha, você não vai conseguir trabalhar com essa api para movimentar seus dados, mas porquê não? por quê a própria api faz o gerenciamento da chave de encriptação, gerando chaves únicas para cada chamada do método gensalt(), caso queira trabalhar dessa forma encriptando o usuário e senha, sugiro que faça sua própria implementação do algoritmo de criptografia, caso contrário movimente somente a senha e trabalhe dessa forma, outro detalhe a se observar, se você permite que existam usuários com logins iguais, já é mais um impeditivo a ser tratado.

1 curtida

realmente eu acabei percenbdo isso até comentei ali em cima,
vou fazer somente c a senha mesmo, e eu vou fazer essa verificação de não poder ser adicionado mais de um login .

opa mano
você poderia me dar uma ajuda?

bom eu tava querendo fazer uma verificação
quando tiver um novo registro em uma tabela
teria como eu saber dessa informação?

Posso ajudar sim!

Mas o ideal seria tu criar um tópico com essa sua nova dúvida e explanar bem ela, assim mais pessoas do fórum conseguem visualizar com facilidade e ajudar também.

2 curtidas


eu tinha postado,
eu sei que terei que usar rotinas, mas a dúvida é como fazer essa verificação se foi inserido um novo registro.