Android中的MD5哈希

Squ*_*onk 86 android md5 cryptography

我有一个简单的Android客户端,需要与简单的C#HTTP侦听器"对话".我想通过在POST请求中传递用户名/密码来提供基本级别的身份验证.

MD5哈希在C#中是微不足道的,并且为我的需求提供了足够的安全性,但我似乎无法在android端找到如何做到这一点.

编辑:只是为了解决有关MD5弱点的问题 - C#服务器运行在我的Android客户端用户的PC上.在许多情况下,他们将使用自己的局域网上的Wi-Fi访问服务器,但他们可能会自己冒险从互联网上访问它.此外,服务器上的服务需要使用MD5的传递到我无法控制的第三方应用程序.

Den*_*sky 216

是您可以使用的实现(更新为使用更新的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 "";
}
Run Code Online (Sandbox Code Playgroud)

虽然不推荐用于甚至涉及基本安全级别的系统(MD5 被认为已损坏且易于利用),但对于基本任务而言,它有时已足够.

  • 向IMO投票,这样下面会得到更正确的答案. (6认同)
  • 0没有照顾,如下所述. (4认同)
  • 有没有没有实现MD5的android操作系统(导致抛出'NoSuchAlgorithmException`)? (3认同)

And*_*nik 46

在Android 2.2中,接受的答案对我不起作用.我不知道为什么,但它正在"吃掉"我的一些零(0). Apache commons也无法在Android 2.2上运行,因为它使用仅从Android 2.3.x开始支持的方法.另外,如果你想只是MD5一个字符串,那么Apache公共文件太复杂了.为什么要让整个库只使用一个小函数...

最后,我在这里找到了以下代码片段,它对我来说非常有用.我希望它对某些人有用......

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;
}
Run Code Online (Sandbox Code Playgroud)

  • 为我工作.我已经改变了**md5.getBytes("UTF-8")**.我用以下代码检查了它:**q4m'x68n6_YDB4ty8VC4&} wqBtn ^ 68W**,结果是**0c70bb931f03b75af1591f261eb77d0b**,而不是*c70bb931f03b75af1591f261eb77d0b*.0到位了 (4认同)

小智 27

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;
}
Run Code Online (Sandbox Code Playgroud)

  • @androiddeveloper你是完全正确的.catch块在这里实现很差,需要有一个return语句,或者在调用m.update时会出现一个空引用错误.另外我不确定,但是这可能不会在单个字节上删除0,我认为它仍然可以在整个32字符哈希上删除前导0.而不是toString(16)我认为String.Format("%032X",bigInt)按预期工作.另外,您可以选择是将大小写还是大写(小写"%032x"). (2认同)

tbr*_*aun 20

如果使用Apache Commons Codec是一个选项,那么这将是一个更短的实现:

String md5Hex = new String(Hex.encodeHex(DigestUtils.md5(data)));
Run Code Online (Sandbox Code Playgroud)

或SHA:

String shaHex= new String(Hex.encodeHex(DigestUtils.sha("textToHash")));
Run Code Online (Sandbox Code Playgroud)

以上来源.

请点击链接并提出他的解决方案,以奖励正确的人.


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

目前的Maven依赖(截至2016年7月6日):

<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.10</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)


wzb*_*zon 12

使用DigestUtils的上述解决方案对我不起作用.在我的Apache commons版本(2013年的最新版本)中没有这样的类.

在一个博客中找到了另一个解决方案.它完美无缺,不需要Apache公共资源.它看起来比上面接受的答案中的代码短一点.

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

您将需要这些导入:

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
Run Code Online (Sandbox Code Playgroud)

  • 最后几行可能只能替换为:return String.Format("%032X",number); 否则我真的很喜欢这个答案. (2认同)

rsi*_*imp 9

这是Andranik和Den Delimarsky在上面的答案的略微变化,但它更简洁,不需要任何按位逻辑.相反,它使用内置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;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您想要返回小写字符串,那么只需更改%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;
    }
}
Run Code Online (Sandbox Code Playgroud)


Pha*_*inh 5

这是 @Andranik 答案的 Kotlin 版本。我们需要更改getBytestoByteArray(不需要添加字符集UTF-8,因为默认字符集toByteArray是UTF-8)并将 array[i] 转换为整数

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
}
Run Code Online (Sandbox Code Playgroud)

希望有帮助