我在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 token )验证了标准Java的编码结果。该代码在标准Java程序中可以正常工作,但在Android程序中则无法工作。我进行了很多搜索,无法找出问题所在。任何人都经历过吗?

这是标准Java和android的结果...
  • Java(和PHP):fH/+pz0J5XcPZH/d608zGSn7FKA=
  • Android程序:fH/vv73vv709Ce+/vXcPZH/vv73vv71PMxkp77+9FO+/vQ==

  • 进一步研究它,我可以确定它是hmac函数,而不是Base64编码,因为比较这些hmac值时,Android版本与Java程序相比具有各种额外的空格和其他未知字符符号。

    任何帮助表示赞赏!

    最佳答案

    我想这是一个字符串编码问题。

    你在这里做什么?

            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的字符串)。

    10-07 19:20
    查看更多