web-dev-qa-db-fra.com

Comment hacher une chaîne dans Android?

Je travaille sur une application Android et j'ai quelques chaînes que je voudrais crypter avant de les envoyer à une base de données. J'aimerais que quelque chose de sécurisé, facile à mettre en œuvre, génère la même chose chaque fois qu'il reçoit les mêmes données, il en résulte de préférence une chaîne qui reste une longueur constante, quelle que soit la taille de la chaîne qui lui est transmise. Peut-être que je cherche un hachage.

49
Jorsher

Cet extrait calcule md5 pour une chaîne donnée

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 "";
}

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

J'espère que cela vous sera utile

86
Antonio

Cette fonction ci-dessus de ( http://www.androidsnippets.org/snippets/52/index.html ) est défectueuse. Si l'un des chiffres du messageDigest n'est pas une valeur hexadécimale à deux caractères (c'est-à-dire 0x09), cela ne fonctionne pas correctement car il ne remplit pas avec un 0. Si vous recherchez autour, vous trouverez cette fonction et des plaintes à son sujet. ne fonctionne pas. En voici une meilleure trouvée dans la section commentaire de cette page , que j'ai légèrement modifiée:

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 "";
}
64
Craig B

ne fonctionne pas méthode:

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 "";
}

résultat: 1865e62e7129927f6e4cd9bff104f0 (longueur 30)

méthode de travail:

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!
    }
}

résultat: 1865e62e7129927f6e4c0d9bff1004f0 (longueur 32)

21
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 réponse ci-dessus est presque 100% correcte. Il échouera avec 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();
    }

Besoin de la longueur du tableau d'octets et non de la chaîne.

5
Sandstone

Avec la solution @Donut, avec les caractères encodés UTF-8 (ex: é), vous devez utiliser getBytes("UTF-8"). Voici ma correction de la méthode digest:

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 solution de Donut dans une seule fonction:

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

Si vous n'aviez pas de contraintes de sécurité et que vous vouliez simplement convertir String en un entier unique. Je l'écris parce que c'est ce que j'ai cherché et atteint ici.

String my_key
int my_key.hashCode()

si vous avez jusqu'à 10 caractères, il sera même unique. Voir aussi https://stackoverflow.com/a/17583653/1984636

2
sivi

Ce qui suit a fonctionné pour moi sur Android sans tronquer le 0):

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

Ce "0" ne manque pas

  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 "";
    }
2
levonfly

si vous utilisez de la goyave:

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
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)));
}

Il est tard pour l'auteur, mais avant cela, j'obtiens Integer.toHexString(0xff&b), qui supprime les 0 en tête de la chaîne hexadécimale. Cela m'a fait du mal pendant longtemps. J'espère utile pour certains gars.

1
kyon