6

我在 android 上遇到了一些 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=
  • 安卓程序:fH/vv73vv709Ce+/vXcPZH/vv73vv71PMxkp77+9FO+/vQ==

仔细研究一下,我确信它是 hmac 函数而不是 Base64 编码,因为比较那些 hmac 值 Android 版本与 Java 程序相比,它有各种额外的空格和其他未知字符符号。

任何帮助表示赞赏!

4

1 回答 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 之类的东西)。

于 2011-08-13T01:40:33.943 回答