3

次のように、JavaベースのコードをC#に変換しようとしています。

元のJavaコード。

String str2 = "5f1fa09364a6ae7e35a090b434f182652ab8dd76:{\"expiration\": 1353759442.0991001, \"channel\": \"dreamhacksc2\", \"user_agent\": \".*"

Mac localMac = Mac.getInstance("HmacSHA1");
localMac.init(new SecretKeySpec("Wd75Yj9sS26Lmhve".getBytes(), localMac.getAlgorithm()));
String str3 = new BigInteger(1, localMac.doFinal(str2.getBytes())).toString(16);
Object[] arrayOfObject2 = new Object[2];
arrayOfObject2[0] = str3;
arrayOfObject2[1] = URLEncoder.encode(str2);
String str4 = String.format("%s:%s", arrayOfObject2);

そしてこれが私のWinRTベースのc#コードです

var token="5f1fa09364a6ae7e35a090b434f182652ab8dd76:{\"expiration\": 1353759442.0991001, \"channel\": \"dreamhacksc2\", \"user_agent\": \".*";

var encoding = new System.Text.UTF8Encoding();
var key = encoding.GetBytes("Wd75Yj9sS26Lmhve");
//var key = Convert.FromBase64String("Wd75Yj9sS26Lmhve");

var tokenData = encoding.GetBytes(token);

var result = HmacSha1(key, tokenData);

var hexString = new BigInteger(result).ToString("x");
var urlEncoded = System.Net.WebUtility.UrlEncode(token);

var combined = String.Format("{0}:{1}", hexString, urlEncoded);

WinRTで実行しているときにhmacsha1が機能します。

    public static byte[] HmacSha1(byte[] key, byte[] data)
    {
        var crypt = Windows.Security.Cryptography.Core.MacAlgorithmProvider.OpenAlgorithm("HMAC_SHA1");
        var keyBuffer = Windows.Security.Cryptography.CryptographicBuffer.CreateFromByteArray(key);
        var cryptKey = crypt.CreateKey(keyBuffer);

        var dataBuffer = Windows.Security.Cryptography.CryptographicBuffer.CreateFromByteArray(data);
        var signBuffer = Windows.Security.Cryptography.Core.CryptographicEngine.Sign(cryptKey, dataBuffer);

        byte[] result;
        Windows.Security.Cryptography.CryptographicBuffer.CopyToByteArray(signBuffer, out result);

        return result;
    }

これが対応するアウトパスです。

(JAVA) 92e893efe72a2f7df6ed409ce35819faba191a63:5f1fa09364a6ae7e35a090b434f182652ab8dd76%3A%7B%22expiration%22%3A+1353759442.0991001%2C+%22channel%22%3A+%22dreamhacksc2%22%2C+%22user_agent%22%3A+%22.*
  (C#) 63b10e1d8e9f99cd7fba2ed46fe8e4a4a40222f5:5f1fa09364a6ae7e35a090b434f182652ab8dd76%3A%7B%22expiration%22%3A+1353759442.0991001%2C+%22channel%22%3A+%22dreamhacksc2%22%2C+%22user_agent%22%3A+%22.*

上に示したように、javaとc#からのHMAC_SHA1の出力は等しくありません。何か案は?エンコーディングの問題を実行していますか?

4

3 に答える 3

4

3つのヒント:

  1. 私があなたのJavaコードをテストしたとき、私はstr3のこの値を受け取りました:f52202a4a4e4e86fd42eba7fcd999f8e1d0eb163それはあなたによって投稿されたJavaとC#の両方の結果とは異なります。(このオンラインツールも私の結果を計算します。)

  2. ウィキペディアにはが含まれていますが、Javaコードとオンライン計算機に基づいて正しいようです。"The quick brown fox jumps over the lazy dog", "key", "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9"最初のステップでは、トリプレットを使用してJavaおよびC#コードをテストします。

  3. BigInterger.toString(16)を使用してバイト配列を16進文字列に変換することはお勧めできません。これは、バイト配列が1つ以上のゼロ桁(または16進?)で始まる場合、変換された16進文字列には先行0文字が含まれないためです。 。

于 2012-11-24T18:57:04.277 に答える
4

単純にして、コードを同じにしてください。

Java:

public static String toHexString(byte[] bytes) {
    StringBuilder sb = new StringBuilder(bytes.length * 2);
    for (int i = 0; i < bytes.length; ++i) {
        sb.append(String.format("%02x", bytes[i]));
    }
    return sb.toString();
}

public static void main(String[] args) {
    String str2 = "5f1fa09364a6ae7e35a090b434f182652ab8dd76:{\"expiration\": 1353759442.0991001, \"channel\": \"dreamhacksc2\", \"user_agent\": \".*";
    Mac localMac;
    try {
        localMac = Mac.getInstance("HmacSHA1");

        localMac.init(new SecretKeySpec("Wd75Yj9sS26Lmhve"
                .getBytes("UTF-8"), localMac.getAlgorithm()));
        byte[] result = localMac.doFinal(str2.getBytes("UTF-8"));
        String hexString = toHexString(result);
        System.out.println(hexString);
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }

}

結果:

f52202a4a4e4e86fd42eba7fcd999f8e1d0eb163

C#:

var token = "5f1fa09364a6ae7e35a090b434f182652ab8dd76:{\"expiration\": 1353759442.0991001, \"channel\": \"dreamhacksc2\", \"user_agent\": \".*";

var encoding = new System.Text.UTF8Encoding();
var privateKey = "Wd75Yj9sS26Lmhve";
HMACSHA1 hmac_sha1 = new HMACSHA1(encoding.GetBytes(privateKey));
hmac_sha1.Initialize();
byte[] result = hmac_sha1.ComputeHash(encoding.GetBytes(token));

string hexString = String.Join( "", result.Select( a => a.ToString("x2") ));

Console.WriteLine(hexString);

結果:

f52202a4a4e4e86fd42eba7fcd999f8e1d0eb163
于 2012-11-29T21:17:31.587 に答える
1

バイトと文字列を混同しています。の結果はgetBytes()、デフォルトのによって異なります。これは、システムごとに異なる場合があります。

于 2012-11-26T00:27:43.420 に答える