it-swarm.com.de

MD5-Hashing in Android

Ich habe einen einfachen Android -Client, der mit einem einfachen C # -HTTP-Listener "sprechen" muss. Ich möchte eine grundlegende Authentifizierungsebene bereitstellen, indem ich in POST Anfragen den Benutzernamen/das Passwort übergebe.

MD5-Hashing ist in C # trivial und bietet genügend Sicherheit für meine Anforderungen, aber ich kann am Ende von Android scheinbar nicht herausfinden, wie das geht.

EDIT: Nur um die Bedenken bezüglich der MD5-Schwäche auszuräumen - der C # -Server läuft auf den PCs der Benutzer meines Android-Clients. In vielen Fällen greifen sie über WLAN in ihrem eigenen LAN auf den Server zu. Auf eigenes Risiko können sie sich jedoch dafür entscheiden, über das Internet darauf zuzugreifen. Außerdem muss der Dienst auf dem Server Passthrough für das MD5 für eine Drittanbieteranwendung verwenden, auf die ich keinen Einfluss habe.

86
Squonk

Hier ist eine Implementierung, die Sie verwenden können (aktualisiert, um aktuellere Konventionen zu verwenden Java Konventionen - for:each Schleife, StringBuilder anstelle von 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 "";
}

Obwohl es nicht für Systeme empfohlen wird, die selbst die grundlegende Sicherheitsstufe (MD5 gilt als defekt und kann leicht ausgenutzt werden ) betreffen, reicht es manchmal für grundlegende Aufgaben aus.

210
Den Delimarsky

Die akzeptierte Antwort hat bei mir in Android 2.2. Ich weiß nicht warum, aber es hat einige meiner Nullen (0) "gefressen". Apache Commons funktionierten auch nicht auf Android 2.2, da Methoden verwendet werden, die nur ab Android unterstützt werden = 2.3.x.Auch wenn Sie nur einen String MD5 wollen, ist Apache Commons dafür zu komplex.Warum sollte man eine ganze Bibliothek behalten, um nur eine kleine Funktion daraus zu verwenden ...

Schließlich fand ich den folgenden Codeausschnitt hier , der für mich perfekt funktionierte. Ich hoffe, es wird für jemanden nützlich sein ...

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;
}
46
Andranik

Der androidsnippets.com-Code funktioniert nicht zuverlässig, da die Nullen aus dem resultierenden Hash herausgeschnitten zu sein scheinen.

Eine bessere Implementierung ist hier .

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;
}
26
Christian

Wenn die Verwendung von Apache Commons Codec eine Option ist, wäre dies eine kürzere Implementierung:

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

Oder SHA:

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

Quelle für oben.

Bitte folgen Sie dem Link und stimmen Sie seiner Lösung zu, um die richtige Person zu bestimmen.


Maven-Repo-Link: https://mvnrepository.com/artifact/commons-codec/commons-codec

Aktuelle Maven-Abhängigkeit (Stand: 6. Juli 2016):

<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.10</version>
</dependency>
18
tbraun

Die oben beschriebene Lösung mit DigestUtils hat bei mir nicht funktioniert. In meiner Version von Apache Commons (die neueste für 2013) gibt es keine solche Klasse.

Ich habe eine andere Lösung gefunden hier in einem Blog . Es funktioniert perfekt und benötigt keine Apache-Commons. Es sieht ein bisschen kürzer aus als der Code in der oben angegebenen Antwort.

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

Sie benötigen diese Importe:

import Java.math.BigInteger;
import Java.security.MessageDigest;
import Java.security.NoSuchAlgorithmException;
11
wzbozon

Dies ist eine kleine Abwandlung der obigen Antworten von Andranik und Den Delimarsky, die jedoch etwas prägnanter ist und keine bitweise Logik erfordert. Stattdessen wird das eingebaute String.format-Methode zum Konvertieren der Bytes in hexadezimale Zeichenfolgen mit zwei Zeichen (entfernt keine Nullen). Normalerweise würde ich nur ihre Antworten kommentieren, aber ich habe nicht den Ruf, dies zu tun.

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

Wenn Sie stattdessen einen String in Kleinbuchstaben zurückgeben möchten, ändern Sie einfach %02X bis %02x.

Bearbeiten: Mit BigInteger wie mit wzbozon Antwort können Sie die Antwort noch prägnanter machen:

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;
    }
}
9
rsimp

Ich habe eine einfache Bibliothek in Kotlin erstellt.

Add at Root build.gradle

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

bei App build.gradle

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

Verwendung

In Kotlin

val ob = Hasher()

Dann verwende die hash () Methode

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

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

Es werden jeweils MD5 und SHA-1 zurückgegeben.

Mehr zur Bibliothek

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

3
Himanshu Rawat

In unserer MVC-Anwendung generieren wir für lange 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;
    }

und das gleiche in Android Anwendung (Dank hilft 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
Oleg Grabets

ich habe unten Methode verwendet, um mir md5 zu geben, indem ich Zeichenfolge übergebe, für die Sie md5 erhalten möchten

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

In anderen Vorschlägen herrscht eigentlich eine viel zu verschwenderische toHex () -Konvertierung vor.

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
Gena Batsyan

Bitte benutzen Sie SHA-512, MD5 ist unsicher

public static String getSHA512SecurePassword(String passwordToHash) {
    String generatedPassword = null;
    try {
        MessageDigest md = MessageDigest.getInstance("SHA-512");
        md.update("everybreathyoutake".getBytes());
        byte[] bytes = md.digest(passwordToHash.getBytes());
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
        }
        generatedPassword = sb.toString();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    return generatedPassword;
}

Hier ist Kotlin Version von @Andranik Antwort. Wir müssen getBytes in toByteArray ändern (müssen keinen Zeichensatz UTF-8 hinzufügen, da der Standardzeichensatz von toByteArray UTF-8 ist) und Array [i] umwandeln. zu einer ganzen Zahl

fun String.md5(): String? {
    try {
        val md = MessageDigest.getInstance("MD5")
        val array = md.digest(this.toByteArray())
        val sb = StringBuffer()
        for (i in array.indices) {
            sb.append(Integer.toHexString(array[i].toInt() and 0xFF or 0x100).substring(1, 3))
        }
        return sb.toString()
    } catch (e: Java.security.NoSuchAlgorithmException) {
    } catch (ex: UnsupportedEncodingException) {
    }
    return null
}

Hoffe es hilft

0
Phan Van Linh

MD5 ist ein bisschen alt, SHA-1 ist ein besserer Algorithmus hier gibt es ein Beispiel .

( Auch wie sie in diesem Beitrag bemerken, Java behandelt dies von sich aus, nein Android spezifischer Code. )

0
Adam

dies funktioniert perfekt für mich. Ich habe dies verwendet, um MD5 auf LIST Array zu bekommen (und es dann in ein JSON-Objekt zu konvertieren), aber wenn Sie es nur auf Ihre Daten anwenden müssen. Geben Sie format ein und ersetzen Sie JsonObject durch deins.

Besonders wenn Sie eine Nichtübereinstimmung mit python MD5-Implementierung haben, verwenden Sie dies!

private static String md5(List<AccelerationSensor> sensor) {

    Gson gson= new Gson();
    byte[] JsonObject = new byte[0];
    try {
        JsonObject = gson.toJson(sensor).getBytes("UTF-8");
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }

    MessageDigest m = null;

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

    byte[] thedigest = m.digest(JsonObject);
    String hash = String.format("%032x", new BigInteger(1, thedigest));
    return hash;


}
0
mehran