md5

4 respostas
rafaelunp

Amigos,

estou tentando criar uma classe que me retorne o md5 de uma string passada.
Estou com o código md5 em asp, delphi e javaScript que me retornam o mesmo resultado, mas em java nao estou conseguindo. Vejam so:

passando como parametro a String: troca123 o retorno (em asp, delphi e javascript) é: 34d1bee6128a1947122a22ac23f92245

Em java, com o código abaixo o resultado é diferente... alguem pode me ajudar!?

Código Java Utilizado:

package teste;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import sun.misc.BASE64Encoder;

public class Cripto {

    private static Cripto instance;

    private Cripto() {
    }

    public static synchronized Cripto getInstance() // step 1
    {
        if (instance == null) {
            instance = new Cripto();
        }
        return instance;
    }

    public synchronized String encrypt(String plaintext) throws Exception {

        MessageDigest md = null;
        try {
            md = MessageDigest.getInstance("MD5"); // step 2
        } catch (NoSuchAlgorithmException e) {
            throw new Exception(e.getMessage());
        }

        byte raw[] = md.digest(); // step 4
        String hash = (new BASE64Encoder()).encode(raw); // step 5
        return hash; // step 6
    }

    public synchronized boolean check(String plainText, String cryptText ) throws Exception {
        return cryptText.equals( getInstance().encrypt( plainText ) );
    }

    public static void main(String[] args) throws Exception {
        String plain = "troca123";
        String crypt = Cripto.getInstance().encrypt( plain );

        System.out.println( "Plain: " + plain );
        System.out.println( "Crypt: " + crypt );
        System.out.println( "Check: " + Cripto.getInstance().check(plain , crypt ) );
    }


}

4 Respostas

T

O resultado é diferente porque você está convertendo os bytes para base-64, não para hexadecimal.

O
public synchronized String encrypt(String plaintext) throws Exception {

        MessageDigest md = null;
        try {
            md = MessageDigest.getInstance("MD5"); // step 2
        } catch (NoSuchAlgorithmException e) {
            throw new Exception(e.getMessage());
        }

        byte raw[] = md.digest(); // step 4
        String hash = (new BASE64Encoder()).encode(raw); // step 5
        return hash; // step 6
    }

Não faltou dar um md.digest(plaintext.getBytes()); antes de md.digest()?

PS: Cuidado com encoding ao manipular Strings.

rafaelunp

Com base na sugestão dos senhores, refiz a classe e QUASE deu certo.
O unico problema é que agora o retorno está em UPPERCASE, apesar de estar retornando a string correta.

package teste;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Cripto {

    private static Cripto instance;

    private Cripto() {
    }

    public static synchronized Cripto getInstance() // step 1
    {
        if (instance == null) {
            instance = new Cripto();
        }
        return instance;
    }

	public static String byteArrayToHex(byte[] bytes) {
		String retorno = "";
		if (bytes == null || bytes.length == 0) {
			return retorno;
		}
		for (int i=0; i<bytes.length; i++) {
			byte valor = bytes[i];
			int d1 = valor & 0xF;
			d1 += (d1 < 10) ? 48 : 55;
			int d2 = (valor & 0xF0) >> 4;
			d2 += (d2 < 10) ? 48 : 55;
			retorno = retorno + (char)d2 + (char)d1;
		}
		return retorno;
	}

    public synchronized String encrypt(String plaintext) throws Exception {

        MessageDigest md = null;
        try {
            md = MessageDigest.getInstance("MD5"); // step 2
        } catch (NoSuchAlgorithmException e) {
            throw new Exception(e.getMessage());
        }

        byte raw[] = md.digest(plaintext.getBytes());
        return byteArrayToHex(raw);
    }

    public synchronized boolean check(String plainText, String cryptText ) throws Exception {
        return cryptText.equals( getInstance().encrypt( plainText ) );
    }

    public static void main(String[] args) throws Exception {
        String plain = "troca123";
        String crypt = Cripto.getInstance().encrypt( plain );

        System.out.println( "Plain: " + plain );
        System.out.println( "Crypt: " + crypt );
        System.out.println( "Check: " + Cripto.getInstance().check(plain , crypt ) );
    }


}
rafaelglauber

veja:
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html#toLowerCase(java.util.Locale)

use:
crypt.toLowerCase() para ficar 100%

Criado 18 de outubro de 2007
Ultima resposta 18 de out. de 2007
Respostas 4
Participantes 4