MD5 hashing dans Android

j'ai un client android simple qui a besoin de 'parler' à un auditeur C# HTTP simple. Je veux fournir un niveau de base d'authentification en passant nom d'utilisateur/mot de passe dans les requêtes POST.

MD5 hashing est trivial en C# et fournit assez de sécurité pour mes besoins, mais je ne semble pas trouver comment le faire à la fin de l'android.

modifier: juste pour répondre aux préoccupations soulevées à propos de la faiblesse MD5-le C # server fonctionne sur les PC des utilisateurs de mon client android. Dans de nombreux cas, ils accéderont au serveur en utilisant wi-fi sur leurs propres réseaux locaux, mais, à leurs propres risques, ils peuvent choisir d'y accéder à partir de l'internet. Aussi le service sur le serveur doit utiliser le passage pour le MD5 à une application tierce sur laquelle je n'ai aucun contrôle.

71
demandé sur Squonk 2011-01-31 03:03:40

12 réponses

Ici est une application que vous pouvez utiliser (mis à jour pour utiliser plus jusqu'à ce jour les conventions Java - for:each boucle StringBuilder au lieu de StringBuffer ):

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

        // Create Hex String
        StringBuilder hexString = new StringBuilder();
        for (byte aMessageDigest : messageDigest) {
            String h = Integer.toHexString(0xFF & aMessageDigest);
            while (h.length() < 2)
                h = "0" + h;
            hexString.append(h);
        }
        return hexString.toString();

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

bien qu'il ne soit pas recommandé pour les systèmes qui impliquent même le niveau de sécurité de base (MD5 est considéré cassé et peut être facilement exploité ), il est parfois suffisant pour les tâches de base.

193
répondu Den Delimarsky 2014-01-27 20:02:01

la réponse acceptée n'a pas fonctionné pour moi dans Android 2.2. Je ne sais pas pourquoi, mais c'était "manger" certains de mes zéros (0) . Apache commons n'a pas non plus fonctionné sur Android 2.2, car il utilise des méthodes qui ne sont prises en charge qu'à partir D'Android 2.3.x. De plus, si vous voulez simplement MD5 une chaîne, Apache commons est trop complexe pour cela. Pourquoi on devrait garder un ensemble de bibliothèque à utiliser juste une petite fonction...

finalement j'ai trouvé ce qui suit code snippet ici qui a fonctionné parfaitement pour moi. J'espère que ce sera utile pour quelqu'un...

public String MD5(String md5) {
   try {
        java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
        byte[] array = md.digest(md5.getBytes("UTF-8"));
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < array.length; ++i) {
          sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1,3));
       }
        return sb.toString();
    } catch (java.security.NoSuchAlgorithmException e) {
    } catch(UnsupportedEncodingException ex){
    }
    return null;
}
38
répondu Andranik 2018-10-08 08:30:16

le androidsnippets.com le code ne fonctionne pas de manière fiable parce que les 0 semblent être coupés du hachage résultant.

une meilleure implémentation est ici .

public static String MD5_Hash(String s) {
    MessageDigest m = null;

    try {
            m = MessageDigest.getInstance("MD5");
    } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
    }

    m.update(s.getBytes(),0,s.length());
    String hash = new BigInteger(1, m.digest()).toString(16);
    return hash;
}
24
répondu Christian 2016-08-24 10:41:51

si Utiliser Apache Commons Codec est une option, alors ce serait une implémentation plus courte:

String md5Hex = new String(Hex.encodeHex(DigestUtils.md5(data)));

ou SHA:

String shaHex= new String(Hex.encodeHex(DigestUtils.sha("textToHash")));

Source pour ci-dessus.

veuillez suivre le lien et noter sa solution pour attribuer la bonne personne.


repo Maven lien: https://mvnrepository.com/artifact/commons-codec/commons-codec

dépendance Maven actuelle (au 6 juillet 2016):

<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.10</version>
</dependency>
16
répondu tbraun 2017-05-23 11:47:30

une solution ci-dessus en utilisant des DigestUtils n'a pas fonctionné pour moi. Dans ma version D'Apache commons (la dernière pour 2013) il n'y a pas de telle classe.

j'ai trouvé une autre solution ici dans un blog . Il fonctionne parfaitement et n'a pas besoin d'Apache commons. Il semble un peu plus court que le code dans la réponse acceptée ci-dessus.

public static String getMd5Hash(String input) {
    try {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] messageDigest = md.digest(input.getBytes());
        BigInteger number = new BigInteger(1, messageDigest);
        String md5 = number.toString(16);

        while (md5.length() < 32)
            md5 = "0" + md5;

        return md5;
    } catch (NoSuchAlgorithmException e) {
        Log.e("MD5", e.getLocalizedMessage());
        return null;
    }
}

vous aurez besoin de ces importations:

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
11
répondu wzbozon 2013-12-05 10:57:38

c'est une légère variation des réponses D'Andranik et Den Delimarsky ci-dessus, mais c'est un peu plus concis et ne nécessite pas de logique bitwise. Il utilise plutôt la méthode String.format intégrée pour convertir les octets en chaînes hexadécimales à deux caractères (doesn't strip 0's). Normalement, je voudrais juste commenter leurs réponses, mais je n'ai pas la réputation de le faire.

public static String md5(String input) {
    try {
        MessageDigest md = MessageDigest.getInstance("MD5");

        StringBuilder hexString = new StringBuilder();
        for (byte digestByte : md.digest(input.getBytes()))
            hexString.append(String.format("%02X", digestByte));

        return hexString.toString();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
        return null;
    }
}

si vous souhaitez retourner une chaîne de caractères minuscule à la place, alors changez %02X à %02x .

Edit: En utilisant BigInteger comme avec la réponse de wzbozon, vous pouvez rendre la réponse encore plus concise:

public static String md5(String input) {
    try {
        MessageDigest md = MessageDigest.getInstance("MD5");
        BigInteger md5Data = new BigInteger(1, md.digest(input.getBytes()));
        return String.Format("%032X", md5Data);
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
        return null;
    }
}
7
répondu rsimp 2017-01-18 16:54:19

j'ai fait une simple bibliothèque à Kotlin.

ajouter à la construction de la racine.Grad

allprojects {
        repositories {
            ...
            maven { url 'https://jitpack.io' }
        }
    }

à App build.Grad

implementation 'com.github.1AboveAll:Hasher:-SNAPSHOT'

Utilisation

In Kotlin

val ob = Hasher()

puis utiliser la méthode hash ()

ob.hash("String_You_Want_To_Encode",Hasher.MD5)

ob.hash("String_You_Want_To_Encode",Hasher.SHA_1)

il retournera MD5 et SHA-1 respectivement.

pour en savoir plus sur la bibliothèque

https://github.com/1AboveAll/Hasher

2
répondu Himanshu Rawat 2018-09-12 15:54:06

MD5 est un peu vieux, SHA-1 est un meilleur algorithme, il y a un exemple ici .

( aussi comme ils le notent dans ce post, Java gère ce sur lui-même, pas de code spécifique Android. )

1
répondu Adam 2017-05-23 12:18:24

dans notre application MVC nous produisons pour long param

using System.Security.Cryptography;
using System.Text;
    ...
    public static string getMD5(long id)
    {
        // convert
        string result = (id ^ long.MaxValue).ToString("X") + "-ANY-TEXT";
        using (MD5 md5Hash = MD5.Create())
        {
            // Convert the input string to a byte array and compute the hash. 
            byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(result));

            // Create a new Stringbuilder to collect the bytes and create a string.
            StringBuilder sBuilder = new StringBuilder();
            for (int i = 0; i < data.Length; i++)
                sBuilder.Append(data[i].ToString("x2"));

            // Return the hexadecimal string. 
            result = sBuilder.ToString().ToUpper();
        }

        return result;
    }

et même dans L'application Android (thenk aide Andranik)

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
...
public String getIdHash(long id){
    String hash = null;
    long intId = id ^ Long.MAX_VALUE;
    String md5 = String.format("%X-ANY-TEXT", intId);
    try {
        MessageDigest md = java.security.MessageDigest.getInstance("MD5");
        byte[] arr = md.digest(md5.getBytes());
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < arr.length; ++i)
            sb.append(Integer.toHexString((arr[i] & 0xFF) | 0x100).substring(1,3));

        hash = sb.toString();
    } catch (NoSuchAlgorithmException e) {
        Log.e("MD5", e.getMessage());
    }

    return hash.toUpperCase();
}
1
répondu Oleg Grabets 2014-11-19 08:32:42

j'ai utilisé la méthode ci-dessous pour me donner md5 en passant chaîne pour laquelle vous voulez obtenir md5

public static String getMd5Key(String password) {

//        String password = "12131123984335";

        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(password.getBytes());

            byte byteData[] = md.digest();

            //convert the byte to hex format method 1
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < byteData.length; i++) {
                sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
            }

            System.out.println("Digest(in hex format):: " + sb.toString());

            //convert the byte to hex format method 2
            StringBuffer hexString = new StringBuffer();
            for (int i = 0; i < byteData.length; i++) {
                String hex = Integer.toHexString(0xff & byteData[i]);
                if (hex.length() == 1) hexString.append('0');
                hexString.append(hex);
            }
            System.out.println("Digest(in hex format):: " + hexString.toString());

            return hexString.toString();

        } catch (Exception e) {
            // TODO: handle exception
        }

        return "";
}
0
répondu Ghanshyam Patidar 2016-03-19 05:46:34

la conversion toHex() beaucoup trop coûteuse prévaut dans d'autres suggestions, vraiment.

private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();

public static String md5string(String s) {
    return toHex(md5plain(s));
}

public static byte[] md5plain(String s) {
    final String MD5 = "MD5";
    try {
        // Create MD5 Hash
        MessageDigest digest = java.security.MessageDigest.getInstance(MD5);
        digest.update(s.getBytes());
        return digest.digest();
    } catch (NoSuchAlgorithmException e) {
        // never happens
        e.printStackTrace();
        return null;
    }
}

public static String toHex(byte[] buf) {
    char[] hexChars = new char[buf.length * 2];
    int v;
    for (int i = 0; i < buf.length; i++) {
        v = buf[i] & 0xFF;
        hexChars[i * 2] = HEX_ARRAY[v >>> 4];
        hexChars[i * 2 + 1] = HEX_ARRAY[v & 0x0F];
    }
    return new String(hexChars);
}
0
répondu Gena Batsyan 2016-03-25 11:41:29

La condition des solutions pour la Scala de langue (un peu plus court):

def getMd5(content: Array[Byte]) =
    try {
        val md = MessageDigest.getInstance("MD5")
        val bytes = md.digest(content)
        bytes.map(b => Integer.toHexString((b + 0x100) % 0x100)).mkString
    } catch {
        case ex: Throwable => null
    }
-1
répondu david.perez 2014-07-11 11:41:14