Criptografia MD5 não funciona com DAO

14 respostas
M

Galera estou tentando criptografar uma senha no momento da inserção do banco usando o padrão DAO, porém não funciona. Alguém pode me dizer porque. Tenho uma tabela login com os seguintes campos: cod autoincremento, usuario e senha. No momento da inserção colocando o MD5(?) na frente do parâmetro, não ocorre a inserção.
Meu DAO

public void inserirUsuario(Login usuario) throws SQLException{
        PreparedStatement stmt = this.con.prepareStatement("insert into login (usuario, senha) values(?,MD5(?))");
        stmt.setString(1,usuario.getUsuario());
        stmt.setString(2, usuario.getSenha());
        stmt.execute();
        stmt.close();
        
        
        
    }

14 Respostas

Hebert_Coelho

Seu banco tem a função MD5? Se você rodar esse comando na tela do banco de dados, funciona?

jeffev

Bom… Não sei se é a melhor maneira, mas eu mando a senha para o DAO já em MD5.

Hebert_Coelho

jeffev:
Bom… Não sei se é a melhor maneira, mas eu mando a senha para o DAO já em MD5.
Pois é. Eu também faço desse modo.
Por isso perguntei se o banco dele tem essa função MD5. Seria o primeiro banco que eu vejo essa função e a primeira vez que vejo um desenvolvedor utilizar.
O.o

M

Como assim mandar a senha para o DAO já em MD5.

Rodrigo_Sasaki

Gere o hash MD5 da senha antes de enviar para o DAO, creio que possa utilizar MessageDigest

marvinla

Dá algum erro de sintaxe na execução?
Cola o stack trace da exceção aqui.

juniorsatanas

erro

juniorsatanas
package br.app.sisau.service;

import br.app.sisau.beans.AuditoriaBean;
import br.app.sisau.beans.PessoaBean;
import br.app.sisau.daos.AuditoriaJpaDao;
import br.app.sisau.daos.PessoaJpaDao;
import br.app.sisau.security.beans.PapelBean;
import br.app.sisau.security.daos.PapelJpaDao;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.Random;
import org.apache.log4j.Logger;


public class Service {

    private static final Logger logger = Logger.getLogger(Service.class);
    /*
     * Objeto para implementacao do singleton
     */
    private static Service instance = new Service();

    /*
     * Metodo construtor privado, para evitar
     * multipla instanciacao
     */
    private Service() {
    }
    /*
     * Metodo que retorna a unica instancia da classe
     */

    public static Service getInstance() {
        return instance;
    }

    public String encryptPassword(String input) {
        MessageDigest md = null;
        String result = input;
        if (input != null) {
            try {
                md = MessageDigest.getInstance("MD5"); //or "SHA-1"
                md.update(input.getBytes());
                BigInteger hash = new BigInteger(1, md.digest());
                result = hash.toString(16);
            } catch (NoSuchAlgorithmException ex) {
                logger.debug(ex);
            }
            while (result.length() < 32) {
                result = "0" + result;
            }
        }
        return result;
    }

    /*
     * Gera senha randômica da combinação de números e caracteres
     * maíusculas e minúsculas.
     * Parâmetro de passagem é o tamanho da senha a ser gerada
     */
    public String getRandomPassword(int length) {
        char[] ALL_CHARS = new char[62];
        Random RANDOM = new Random();

        for (int i = 48, j = 0; i < 123; i++) {
            if (Character.isLetterOrDigit(i)) {
                ALL_CHARS[j] = (char) i;
                j++;
            }
        }

        char[] result = new char[length];
        for (int i = 0; i < length; i++) {
            result[i] = ALL_CHARS[RANDOM.nextInt(ALL_CHARS.length)];
        }
        return new String(result);
    }

    public PessoaBean realizaLogin(String username, String password) throws Exception {
        if ("".equals(username)) {
            throw new Exception("Username não pode ser vazio");
        }
        if ("".equals(password)) {
            throw new Exception("Senha não pode ser vazia");
        }
        PessoaBean cadastrada = new PessoaJpaDao().findByUsername(username);
        String encryptedPassword = encryptPassword(password);

        if (!encryptedPassword.equals(cadastrada.getPassword())) {
            throw new Exception("Senha inválida");
        }
        return cadastrada;
    }

    public List<PessoaBean> listarPessoas() {
        return new PessoaJpaDao().findEntities();
        //return new PessoaJpaDao().pesquisar();
    }

    public PessoaBean pesquisarPessoaEmail(String email) throws Exception {
        return new PessoaJpaDao().findByEmail(email);
    }

    public List<PessoaBean> pesquisarPessoaCriteria(String termoPesquisa) {
        return new PessoaJpaDao().pesquisarCriteria(termoPesquisa);
    }

    public void cadastrarPessoa(PessoaBean pessoa){       
        new PessoaJpaDao().create(pessoa);
    }

    public void atualizarPessoa(PessoaBean pessoa){
        new PessoaJpaDao().update(pessoa);
    }

    public void excluirPessoa(PessoaBean pessoa){
        new PessoaJpaDao().delete(pessoa);
    }
    
    public List<AuditoriaBean> listarAuditorias(){
        return new AuditoriaJpaDao().findEntities();
    }
//
    public List<PessoaBean> pesquisarPessoas(String termoPesquisa) {
        return new PessoaJpaDao().pesquisar(termoPesquisa);
    }
    
    public List<PessoaBean> pesquisarPessoas() {
        return new PessoaJpaDao().pesquisar();
    }
 
    public PessoaBean pesquisarPessoa(PessoaBean pessoa) {
        return new PessoaJpaDao().findEntity(pessoa.getId());
    }

  }
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.app.sisau.jsf;

import br.app.sisau.beans.PessoaBean;
import br.app.sisau.service.AuditoriaService;
import br.app.sisau.service.I18nService;
import br.app.sisau.service.MailService;
import br.app.sisau.service.Service;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import org.apache.log4j.Logger;

/**
 *
 * @author Herick
 */
@ManagedBean(name = "loginMB")
@ViewScoped
public class LoginManagedBean implements Serializable {

    private static final Logger logger = Logger.getLogger(LoginManagedBean.class);
    private String username;
    private String password;
    private String email;
    private boolean firstTimeLogin = false;
    private PessoaBean pessoa;

    public LoginManagedBean() {
        List<PessoaBean> listaPessoas = Service.getInstance().listarPessoas();
        if (listaPessoas.isEmpty()) {
            firstTimeLogin = true;
            pessoa = new PessoaBean();
        } else {
            firstTimeLogin = false;
        }
    }

    public PessoaBean getPessoa() {
        return pessoa;
    }

    public void setPessoa(PessoaBean pessoa) {
        this.pessoa = pessoa;
    }

    public boolean isFirstTimeLogin() {
        return firstTimeLogin;
    }

    public void setFirstTimeLogin(boolean firstTimeLogin) {
        this.firstTimeLogin = firstTimeLogin;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String doLogin() {
        if (isCamposValidos()) {
            try {
                PessoaBean pessoa = Service.getInstance().realizaLogin(this.username, this.password);

                FacesContext ctx = FacesContext.getCurrentInstance();
                Map sessionMap = ctx.getExternalContext().getSessionMap();
                UserSessionManagedBean userSessionMB = (UserSessionManagedBean) sessionMap.get("userSessionMB");
                if (userSessionMB == null) {
                    userSessionMB = new UserSessionManagedBean();
                    sessionMap.put("userSessionMB", userSessionMB);
                }
                userSessionMB.setLoggedUser(pessoa);
                
                AuditoriaService.getInstance().gravarAcaoUsuario(pessoa, "Login no Sistema", "Login", "Efetuou login no sistema.");
                
                return "pessoas?faces-redirect=true";

            } catch (Exception e) {
                this.username = "";
                this.password = "";
                FacesContext.getCurrentInstance().addMessage("invalido", new FacesMessage(e.getMessage()));
                return "login";
            }
        } else {
            return "login";
        }
    }

    private boolean isCamposValidos() {
        boolean camposValidos = true;
        if ("".equals(username)) {
            FacesContext.getCurrentInstance().addMessage("invalido", new FacesMessage(I18nService.getInstance().getKey("username_required")));
            camposValidos = false;
        }
        if ("".equals(password)) {
            FacesContext.getCurrentInstance().addMessage("invalido", new FacesMessage(I18nService.getInstance().getKey("password_required")));
            camposValidos = false;
        }
        return camposValidos;
    }

    public String doLogout() {
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("userSessionMB");
        return "login?faces-redirect=true";
    }

    public void recuperarSenha() {
        try {
            PessoaBean pessoa = Service.getInstance().pesquisarPessoaEmail(email);

            if (pessoa == null) {
                FacesContext.getCurrentInstance().addMessage("invalido", new FacesMessage(I18nService.getInstance().getKey("mail_not_found")));
            } else {

                FacesContext.getCurrentInstance().addMessage("invalido", new FacesMessage(I18nService.getInstance().getKey("mail_sent")));
                String password = Service.getInstance().getRandomPassword(8);
                pessoa.setPassword(Service.getInstance().encryptPassword(password));

                Service.getInstance().atualizarPessoa(pessoa);

                String subject = "Recuperação de Senha";
                String setTo = pessoa.getEmail();
                //Para envio de e-mail com HTML: Aspas duplas devem ser precedidas de barra.
                String message = "Sua senha foi alterada pelo sistema. \n"
                        + "Sua nova senha encontra-se abaixo: \n"
                        + "Nome de Usuário - " + pessoa.getUsername() + " \n"
                        + "Senha - " + password;
                MailService.getInstance().sendMail(subject, setTo, message);
            }

        } catch (Exception ex) {
            FacesContext.getCurrentInstance().addMessage("invalido", new FacesMessage(ex.getMessage()));
        }
    }

    public void cadastrar() {
        pessoa.setPassword(Service.getInstance().encryptPassword(password));
        Service.getInstance().cadastrarPessoa(pessoa);
        firstTimeLogin = false;
        FacesContext.getCurrentInstance().addMessage("invalido", new FacesMessage(I18nService.getInstance().getKey("add_success")));

        String subject = "Cadastro no Sistema";
        String setTo = pessoa.getEmail();
        //Para envio de e-mail com HTML: Aspas duplas devem ser precedidas de barra.
        String message = "Seu cadastro foi efetuado no sistema. \n"
                + "Seus dados: \n"
                + "Nome de Usuário - " + pessoa.getUsername() + " \n"
                + "Senha - " + password;
        MailService.getInstance().sendMail(subject, setTo, message);

        pessoa = new PessoaBean();
    }
}
M

Não apresenta nem tipo erro. o que acontece é que o servlet que fará a inserção no banco não o faz, ou seja, não gera a página de resposta.

ViniGodoy

Usar MD5 numa senha de banco é tão seguro quanto aquela substituição de letras por símbolos que as meninas fazem em seus diários.

Se você quiser garantir um mínimo de segurança no seu BD, salve a senha com SHA-256, preferencialmente usando SALT:
https://www.owasp.org/index.php/Hashing_Java

M

Resolvido. De acordo com o meu código, testando a instrução diretamente no banco, faltava ajustar o tamanho do campo declarado na tabela com o tamanho da chave criptografa gerada.

juniorsatanas

Meu Grande amigo VINI tem toda razão !

jweibe

Use a biblioteca Cammons Codec ela disponibiliza diversos tipos de criptografia.

ViniGodoy

Não entendi muito o propósito desse MD5.

Você está enviando a senha em texto plano pela rede (assim, pode ser vista tanto no firebug, quanto com um sniffer, como o wireshark). E está só salvando ela com um algorítmo fraquíssimo de hash no banco. Na verdade, esse algoritmo é tão fraco, que é provável que você consiga reverter a senha só procurando pelo hash dela no google.

Então, qual é o propósito de usar o MD5 desse jeito? Se for para ser assim, salva a senha em texto plano direto.

Criado 12 de setembro de 2012
Ultima resposta 12 de set. de 2012
Respostas 14
Participantes 8