6

Android の一部の HMAC に問題があります。Android hmac-sha1を検索すると、Web全体に表示される次のコードで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 プログラムを作成して (もちろん、Log.v 呼び出しを System.out.println 呼び出しに置き換えて)、Android バージョンと比較できるようにしました。どちらの場合も、base_string とキーに同じテスト値を使用しています。

さらに、いくつかの PHP 関数と検証サーバー (いくつかの OAuth トークンを使用) を使用して、標準の Java からエンコードされた結果を検証しました。コードは標準の Java プログラムでは問題なく動作しますが、Android プログラムでは動作しません。私は多くの検索を行いましたが、何が間違っているのかわかりません。誰もこれを経験したことがありますか?

標準のJavaとAndroidの結果は次のとおりです...

  • Java (および PHP):fH/+pz0J5XcPZH/d608zGSn7FKA=
  • Android プログラム:fH/vv73vv709Ce+/vXcPZH/vv73vv71PMxkp77+9FO+/vQ==

もう少し調べてみると、これらのhmac値を比較すると、Androidバージョンにはあらゆる種類の余分なスペースやその他の未知の文字記号とJavaプログラムがあるため、混乱するBase64エンコードではなく、hmac関数であると確信しています。

どんな助けでも大歓迎です!

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 に答える