it-swarm-es.com

¿Cómo hash una cadena en Android?

Estoy trabajando en una aplicación de Android y tengo un par de cadenas que me gustaría cifrar antes de enviarlas a una base de datos. Me gustaría algo que sea seguro, fácil de implementar, generará lo mismo cada vez que pase los mismos datos y, preferiblemente, dará como resultado una cadena que se mantenga constante sin importar cuán grande sea la cadena que se le pasa. Tal vez estoy buscando un hash.

49
Jorsher

Este fragmento de código calcula md5 para cualquier cadena dada

public String md5(String s) {
    try {
        // Create MD5 Hash
        MessageDigest digest = Java.security.MessageDigest.getInstance("MD5");
        digest.update(s.getBytes());
        byte messageDigest[] = digest.digest();

        // Create Hex String
        StringBuffer hexString = new StringBuffer();
        for (int i=0; i<messageDigest.length; i++)
            hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
        return hexString.toString();

    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    return "";
}

Fuente: http://www.androidsnippets.com/snippets/52/index.html

Espero que esto te sea de utilidad.

86
Antonio

La función anterior de ( http://www.androidsnippets.org/snippets/52/index.html ) es defectuosa. Si uno de los dígitos del messageDigest no es un valor hexadecimal de dos caracteres (es decir, 0x09), no funciona correctamente porque no se rellena con un 0. Si busca, encontrará esa función y quejas sobre ella. no funciona. Aquí, una mejor encontrada en la sección de comentarios de esta página , que modifiqué ligeramente:

public static String md5(String s) 
{
    MessageDigest digest;
    try
    {
        digest = MessageDigest.getInstance("MD5");
        digest.update(s.getBytes(Charset.forName("US-ASCII")),0,s.length());
        byte[] magnitude = digest.digest();
        BigInteger bi = new BigInteger(1, magnitude);
        String hash = String.format("%0" + (magnitude.length << 1) + "x", bi);
        return hash;
    }
    catch (NoSuchAlgorithmException e)
    {
        e.printStackTrace();
    }
    return "";
}
63
Craig B

método de no trabajar:

public static String md5(String s) {
    try {
        // Create MD5 Hash
        MessageDigest digest = Java.security.MessageDigest
                .getInstance("MD5");
        digest.update(s.getBytes());
        byte messageDigest[] = digest.digest();

        // Create Hex String
        StringBuffer hexString = new StringBuffer();
        for (int i = 0; i < messageDigest.length; i++)
            hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
        return hexString.toString();

    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    return "";
}

resultado - 1865e62e7129927f6e4cd9bff104f0 (longitud 30)

método de trabajo:

public static final String md5(final String toEncrypt) {
    try {
        final MessageDigest digest = MessageDigest.getInstance("md5");
        digest.update(toEncrypt.getBytes());
        final byte[] bytes = digest.digest();
        final StringBuilder sb = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            sb.append(String.format("%02X", bytes[i]));
        }
        return sb.toString().toLowerCase();
    } catch (Exception exc) {
        return ""; // Impossibru!
    }
}

resultado - 1865e62e7129927f6e4c0d9bff1004f0 (longitud 32)

20
Yuriy Lisenkov
private static char[] hextable = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

public static String byteArrayToHex(byte[] array) {
    String s = "";
    for (int i = 0; i < array.length; ++i) {
        int di = (array[i] + 256) & 0xFF; // Make it unsigned
        s = s + hextable[(di >> 4) & 0xF] + hextable[di & 0xF];
    }
    return s;
}

public static String digest(String s, String algorithm) {
    MessageDigest m = null;
    try {
        m = MessageDigest.getInstance(algorithm);
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
        return s;
    }

    m.update(s.getBytes(), 0, s.length());
    return byteArrayToHex(m.digest());
}

public static String md5(String s) {
    return digest(s, "MD5");
}
7
Donut

La respuesta anterior es casi 100% correcta. Se fallará con unicode.

    MessageDigest digest;
    try {
        digest = MessageDigest.getInstance("MD5");
        byte utf8_bytes[] = tag_xml.getBytes();
        digest.update(utf8_bytes,0,utf8_bytes.length);
        hash = new BigInteger(1, digest.digest()).toString(16);
    } 
    catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }

Necesita la longitud de la matriz de bytes, no la cadena.

5
Sandstone

Con la solución @Donut, con caracteres codificados en UTF-8 (por ejemplo: é), tiene que usar getBytes("UTF-8"). Aquí está mi corrección del método de digestión:

private static char[] hextable = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};


public static String byteArrayToHex(byte[] array) {
    String s = "";
    for (int i = 0; i < array.length; ++i) {
        int di = (array[i] + 256) & 0xFF; // Make it unsigned
        s = s + hextable[(di >> 4) & 0xF] + hextable[di & 0xF];
    }
    return s;
}

public static String digest(String s, String algorithm) {
    MessageDigest m = null;
    try {
        m = MessageDigest.getInstance(algorithm);
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
        return s;
    }

    try {
        m.update(s.getBytes("UTF-8"));
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
        m.update(s.getBytes());
    }
    return byteArrayToHex(m.digest());
}

public static String md5(String s) {
    return digest(s, "MD5");
}
5
Climbatize

La solución de Donut en una sola función:

private static char[] hextable = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

private static String md5(String s)
{
    MessageDigest digest;
    try
    {
        digest = MessageDigest.getInstance("MD5");
        digest.update(s.getBytes(), 0, s.length());
        byte[] bytes = digest.digest();

        String hash = "";
        for (int i = 0; i < bytes.length; ++i)
        {
            int di = (bytes[i] + 256) & 0xFF;
            hash = hash + hextable[(di >> 4) & 0xF] + hextable[di & 0xF];
        }

        return hash;
    }
    catch (NoSuchAlgorithmException e)
    {
    }

    return "";
}
3
Tanya

Lo siguiente me funcionó en Android sin truncar ningún 0 delante:

MessageDigest md = null;
String digest = null;
    try {
        md = MessageDigest.getInstance("MD5");

        byte[] hash = md.digest(myStringToEncode.getBytes("UTF-8")); //converting byte array to Hexadecimal String
        StringBuilder sb = new StringBuilder(2*hash.length);

        for(byte b : hash){
            sb.append(String.format("%02x", b&0xff));
        }

        digest = sb.toString();

    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }

return digest;
2
Chris

si está utilizando guayaba:

public String generateMd5(String input) {
    HashFunction hf = Hashing.md5();
    Hasher hasher = hf.newHasher();

    HashCode hc = hasher.putString(input, StandardCharsets.UTF_8).hash();

    return hc.toString();
}
1
zack

Si no tenía restricciones de seguridad y solo quería convertir String en un int único. Lo escribo porque es lo que busqué y llegué hasta aquí.

String my_key
int my_key.hashCode()

si tiene hasta 10 caracteres, incluso será único Consulte también https://stackoverflow.com/a/17583653/1984636

1
sivi
MessageDigest md = MessageDigest.getInstance("MD5"); 
md.update('yourstring');
byte[] digest = md.digest();
StringBuffer sb = new StringBuffer();
for (byte b : digest) {
    sb.append(String.format("%02x", (0xFF & b)));
}

Es tarde para el autor, pero antes de esto, obtengo Integer.toHexString(0xff&b), que quita 0s de la cadena hexadecimal. Me hace luchar por mucho tiempo. Esperanza útil para algunos chicos.

1
kyon

Esto no falta '0'

  public static String md5(String string) {
        if (TextUtils.isEmpty(string)) {
            return "";
        }
        MessageDigest md5 = null;
        try {
            md5 = MessageDigest.getInstance("MD5");
            byte[] bytes = md5.digest(string.getBytes());
            String result = "";
            for (byte b : bytes) {
                String temp = Integer.toHexString(b & 0xff);
                if (temp.length() == 1) {
                    temp = "0" + temp;
                }
                result += temp;
            }
            return result;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }
1
levonfly