Android: 如何创建HMAC MD5字符串?

5

我正在尝试创建一个Android MD5哈希字符串,使其等于下面的C#代码:

private string CalculateHMACMd5(string message, string key)
{
     System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
     byte[] keyByte = encoding.GetBytes(key);
     HMACMD5 hmacmd5 = new HMACMD5(keyByte);
     byte[] messageBytes = encoding.GetBytes(message);
     byte[] hashmessage = hmacmd5.ComputeHash(messageBytes);
     string HMACMd5Value = ByteToString(hashmessage);
     return HMACMd5Value;
}

private static string ByteToString(byte[] buff)
{
    string sbinary = "";
    for (int i = 0; i < buff.Length; i++)
    {
        sbinary += buff[i].ToString("X2"); 
    }
    return (sbinary);
}


我目前使用的Android代码 [不能生成相同的C#代码]:

        public static String sStringToHMACMD5(String sData, String sKey) 
        {
            SecretKeySpec key;
            byte[] bytes;
            String sEncodedString = null;
            try 
            {       
                key = new SecretKeySpec((sKey).getBytes(), "ASCII");
                Mac mac = Mac.getInstance("HMACMD5");
                mac.init(key);
                mac.update(sData.getBytes());

                bytes = mac.doFinal(sData.getBytes());
                StringBuffer hash = new StringBuffer();

                for (int i=0; i<bytes.length; i++) {
                    String hex = Integer.toHexString(0xFF &  bytes[i]);
                    if (hex.length() == 1) {
                        hash.append('0');
                    }
                    hash.append(hex);
                }
            sEncodedString = hash.      
            return sEncodedString;
        }

感谢您的提前帮助。

可能是如何在Android中生成HMAC MD5?的重复问题。 - Thilo
1
@Thilo:我亲自检查了你提供的链接,但解决方案并没有起作用。 - Ahmad Kayyali
答案中提供的方法没有使用两个键(数据 + 键)。 - Ahmad Kayyali
2个回答

21
public static String sStringToHMACMD5(String s, String keyString)
    {
        String sEncodedString = null;
        try
        {
            SecretKeySpec key = new SecretKeySpec((keyString).getBytes("UTF-8"), "HmacMD5");
            Mac mac = Mac.getInstance("HmacMD5");
            mac.init(key);

            byte[] bytes = mac.doFinal(s.getBytes("ASCII"));

            StringBuffer hash = new StringBuffer();

            for (int i=0; i<bytes.length; i++) {
                String hex = Integer.toHexString(0xFF &  bytes[i]);
                if (hex.length() == 1) {
                    hash.append('0');
                }
                hash.append(hex);
            }
            sEncodedString = hash.toString();
        }
        catch (UnsupportedEncodingException e) {}
        catch(InvalidKeyException e){}
        catch (NoSuchAlgorithmException e) {}
        return sEncodedString ;
    }

不要忽略异常。记录它们。 - siamii
当然可以,但我会移除Exception以减少上面的代码。 - Basbous

6

“not working”是什么意思?是否出现异常?输出结果不符合预期?等等。

显而易见的是,您正在处理相同的数据两次:

mac.update(sData.getBytes());
bytes = mac.doFinal(sData.getBytes());

要一次处理所有数据,只需使用doFinal()(假设数据不是太大)。 另一个可能出现问题的是密钥格式: String sKey 的格式是什么。理想情况下,您应该使用BASE64编码的字符串,而不是调用getString()


我明白你的意思,你是正确的,请检查我的解决方案,感谢你的提示。 - Basbous
在两个程序中转储(或使用调试器)byte[] keyByte,确保字节相同。对byte[] messageBytes执行相同操作。如果所有这些都匹配,那么byte[] hashmessage也应该匹配,但也要检查一下。如果这些都匹配,则错误可能出现在最终的十六进制编码部分。 - Nikolay Elenkov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接