Android中的HMAC-SHA1与标准Java中的HMAC-SHA1有所不同

6

我在安卓上使用HMAC遇到了问题。我正在使用SHA1算法并使用以下代码,这个代码在搜索android hmac-sha1时出现得到处都是。

        String base_string = "This is a test string";
        String key = "testKey";
        try {
            Mac mac = Mac.getInstance("HmacSHA1");
            SecretKeySpec secret = new SecretKeySpec(key.getBytes("UTF-8"), mac.getAlgorithm());
            mac.init(secret);
            byte[] digest = mac.doFinal(base_string.getBytes());

            String enc = new String(digest);

            // Base 64 Encode the results
            String retVal = Base64.encodeBase64String(enc.getBytes());
            Log.v(TAG, "String: " + base_string);
            Log.v(TAG, "key: " + key);
            Log.v(TAG, "result: " + retVal);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

为了测试这段代码,我创建了一个简单的标准Java程序(当然要使用 System.out.println 调用代替 Log.v 调用),以便与Android版本进行比较。在两种情况下,我都使用相同的测试值作为 base_string 和 key。
此外,我已经通过一些PHP函数和验证服务器(使用一些OAuth令牌)验证了标准Java的编码结果。代码在标准Java程序中运行良好,但在Android程序中却无法正常工作。我做了很多搜索,但是找不出错在哪里。有人遇到过类似问题吗?
以下是标准Java和Android的结果...
Java(和PHP):fH/+pz0J5XcPZH/d608zGSn7FKA=
Android程序:fH/vv73vv709Ce+/vXcPZH/vv73vv71PMxkp77+9FO+/vQ==
更深入地研究后,我确信是 hmac 函数而不是 Base64 编码出现问题,因为将这些 hmac 值进行比较,Android版本与Java程序相比具有所有类型的额外空格和其他未知字符符号。
感谢任何帮助!

1
找不到方法 android.util.Base64.encodeBase64String(...) - AlikElzin-kilaka
1个回答

13

我猜这可能是一个字符串编码问题。

你在这里做什么?

        String enc = new String(digest);

        // Base 64 Encode the results
        String retVal = Base64.encodeBase64String(enc.getBytes());

你可以将字符串转换为字节,然后再转回字节数组(随后进行 base-64 编码)。

但更好的做法是:

        String retVal = Base64.encodeBase64String(digest);

一般来说,如果您想要一个可移植的程序,请永远不要使用String.getBytes()new String(byte[])。而且,绝不要尝试将任意字节数组(在之前不是字符串的情况下)转换为字符串(除了类似Base64的东西)。


哇!太简单了!我知道它会是这样的,但我真的很困惑。谢谢!那立刻解决了问题。 - nlbers
1
你在哪里找到 encodeBase64String() 方法?我无处找到它。 - Gabrielle
@Gabrielle:我只是从问题中复制了这一部分,我不知道这里使用了哪个base64库。但是它们都应该给出相同的结果,因为这是一个明确定义的算法。 - Paŭlo Ebermann
即使我下载org.apache.commons.codec.binary.Base64包并将其添加到我的项目中,我仍然会得到java.lang.NoSuchMethodError:org.apache.commons.codec.binary.Base64.encodeBase64String错误。我找不到错误出现在哪里。 - Gabrielle
2
最终我使用了 android.util.Base64.encode(digest, Base64.DEFAULT) - AlikElzin-kilaka
显示剩余4条评论

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