android — MD5 хеширование в Android" />

MD5 хеширование в Android

У меня есть простой клиент для Android, который должен «общаться» с простым слушателем C # HTTP. Я хочу обеспечить базовый уровень аутентификации, передавая имя пользователя /пароль в запросах POST.

MD5-хэширование в C # тривиально и обеспечивает достаточную безопасность для моих нужд, но я не могу найти, как это сделать на стороне Android.

РЕДАКТИРОВАТЬ: Просто для решения проблем, связанных с слабостью MD5 - сервер C # работает на компьютерах пользователей моего клиента Android. Во многих случаях они будут получать доступ к серверу с помощью Wi-Fi в своих собственных локальных сетях, но на свой страх и риск они могут выбрать доступ к нему из Интернета. Также служба на сервере должна использовать сквозную передачу для MD5 стороннему приложению, которое я не могу контролировать.

80 голосов | спросил Squonk 31 Jam1000000amMon, 31 Jan 2011 03:03:40 +030011 2011, 03:03:40

11 ответов


0

Здесь вы можете использовать реализацию (обновлено) использовать более современные соглашения Java - цикл for:each, StringBuilder вместо 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 "";
}

Хотя это не рекомендуется для систем, в которых используется даже базовый уровень безопасности (MD5 является считается сломанным и может быть легко использовано ), иногда этого достаточно для выполнения основных задач.

ответил Den Delimarsky 31 Jam1000000amMon, 31 Jan 2011 03:08:33 +030011 2011, 03:08:33
0

Принятый ответ не работает для меня в Android 2.2. Я не знаю почему, но это «съело» некоторые из моих нулей (0). Apache commons также не работал на Android 2.2, поскольку он использует методы, которые поддерживаются только начиная с Android 2.3.x. Также, если вы хотите просто MD5-строку, Apache Commons слишком сложен для этого. Почему нужно хранить целую библиотеку, чтобы использовать из нее только небольшую функцию ...

Наконец, я нашел следующий фрагмент кода здесь , который работал отлично для меня. Надеюсь это кому-нибудь пригодится ...

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;
}
ответил Andranik 24 Jpm1000000pmFri, 24 Jan 2014 17:17:48 +040014 2014, 17:17:48
0

Код androidsnippets.com не работает надежно, потому что 0, похоже, вырезаны из полученного хеша.

Лучшая реализация - здесь .

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;
}
ответил Christian 31 Mayam12 2012, 00:55:12
0

Если вы используете кодек Apache Commons, то это будет более короткая реализация:

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

Или SHA:

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

Источник для выше.

Пожалуйста, перейдите по ссылке и проголосуйте за его решение, чтобы наградить правильного человека.


Ссылка на репозиторий Maven: https://mvnrepository.com/artifact/commons-codec /commons-codec

Текущая зависимость Maven (по состоянию на 6 июля 2016 года):

<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.10</version>
</dependency>
ответил tbraun 20 Maypm13 2013, 20:13:05
0

Решение выше с использованием DigestUtils не работает для меня. В моей версии Apache Commons (последняя версия на 2013 год) такого класса нет.

Я нашел другое решение здесь, в одном блоге . Он отлично работает и не нуждается в Apache Commons. Это выглядит немного короче, чем код в принятом ответе выше.

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

Вам понадобится этот импорт:

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
ответил wzbozon 5 ThuEurope/Moscow2013-12-05T14:57:38+04:00Europe/Moscow12bEurope/MoscowThu, 05 Dec 2013 14:57:38 +0400 2013, 14:57:38
0

Это небольшая вариация ответов Андраника и Дена Делимарского выше, но она немного более краткая и не требует побитовой логики. Вместо этого он использует встроенный метод String.format для преобразования байтов в шестнадцатеричные строки из двух символов (не обнуляет 0). Обычно я просто комментирую их ответы, но у меня нет репутации, чтобы это делать.

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

Если вы хотите вместо этого вернуть строчную строку, просто измените %02X на %02x

Изменить: Используя BigInteger, как в ответе wzbozon, вы можете сделать ответ еще более кратким:

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;
    }
}
ответил rsimp 10 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowSat, 10 Sep 2016 01:30:38 +0300 2016, 01:30:38
0

Я сделал простую библиотеку в Котлине.

Добавить в Root build.gradle

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

в приложении build.gradle

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

Использование

В Котлине

val ob = Hasher()

Тогда используйте метод hash ()

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

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

Он вернет MD5 и SHA-1 соответственно.

Подробнее о библиотеке

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

ответил Himanshu Rawat 28 AMpSat, 28 Apr 2018 11:37:33 +030037Saturday 2018, 11:37:33
0

В нашем приложении MVC мы генерируем длинные параметры

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

и то же самое в приложении для Android (затем помогает 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();
}
ответил Oleg Grabets 19 32014vEurope/Moscow11bEurope/MoscowWed, 19 Nov 2014 11:32:42 +0300 2014, 11:32:42
0

MD5 немного стар, SHA-1 - лучший алгоритм, здесь есть пример .

( Кроме того, как отмечается в этом посте, Java обрабатывает это самостоятельно, без кода для Android. )

ответил Adam 16 AM00000030000004831 2012, 03:54:48
0

Я использовал метод ниже, чтобы дать мне md5, передав строку, для которой вы хотите получить 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 "";
}
ответил Ghanshyam Patidar 17 MaramThu, 17 Mar 2016 10:24:23 +03002016-03-17T10:24:23+03:0010 2016, 10:24:23
0

Предлагаемые решения для языка Scala (немного короче):

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
    }
ответил david.perez 11 J000000Friday14 2014, 15:33:44

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132