2

Windows Phone 7 には、ANID と呼ばれる匿名ユーザー ID プロパティがありました。Windows Phone 8 ではこれが ANID2 に置き換えられました。違いは、ANID2 がアプリの発行者 ID に依存することです。

MSDNの次のコード サンプルが示すように、ANID を ANID2 に変換することができます。必要なのは元の WP7 ANID とパブリッシャー ID (guid) だけです。問題は、例が C++ であることです。私はそれをC#に移植しようとしてきましたが、成功しませんでした。

アルゴリズム自体は非常に簡単です。

var data = HMAC(ANID, publisherId) // Uses SHA-256
var result = ToBase64(data)

問題は、結果が一致しないことです。2 つのアプリ (WP7 と WP8) を作成し、同じデバイスで実行してから、パブリッシャー GUID を使用して WP7 アプリから ANID を変換することで、C++ が正しく動作することを確認しました。C++ では、変換された ANID2 とデバイスからの ANID2 が一致します。C# では、変換された ANID2 は別のものです。

C# コードは単純です。

        var anidBytes = System.Text.Encoding.UTF8.GetBytes(this.anidBox.Text);
        var publisherGuid = Guid.Parse(this.publisherBox.Text.ToUpper());

        var macObject = new HMACSHA256(anidBytes);
        var hashed = macObject.ComputeHash(publisherGuid.ToByteArray());

        var result = Convert.ToBase64String(hashed);

C++ 版では CNG (Cryptography API: Next Generation) と呼ばれるものを使用します。それからのいくつかのコードは次のとおりです。

BCryptOpenAlgorithmProvider(&Algorithm, BCRYPT_SHA256_ALGORITHM, NULL, BCRYPT_ALG_HANDLE_HMAC_FLAG);
BCryptGetProperty(Algorithm,BCRYPT_OBJECT_LENGTH,reinterpret_cast<BYTE*>(&HashObjectLength),PropertyLength,&PropertyLength,0);
BCryptCreateHash(Algorithm, &Hash, HashObject, HashObjectLength, pAnidId, dwAnidLength, 0);
BCryptHashData(Hash, const_cast<BYTE*>(pPublisherId), dwPublisherIdLength, 0);
BCryptFinishHash(Hash, pUniqueId, GETDEVICEUNIQUEID_V1_OUTPUT, 0);

その後、「pUniqueId」はカスタムビルド関数を使用して Base64 に変換されます。

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

更新: Visual Studio は、anidBytes (C#) と pAnidId (C++) (これはバイトに変換された ANID 文字列) の両方の長さが 44 であることを報告します。 これは、C# デバッガーがバイト配列を報告する方法です。

C# バイト配列

C++ デバッガーは次のとおりです。 C++ バージョン

私は C++ を知らないので、これら 2 つが同一かどうかはわかりません。それらはそうですが、C++ にはそれぞれの後にこれらの '\0' 文字があり、それで問題ないかどうかわかりません。どちらの場合も長さは 44 と報告されているので、そうだと思います。

もう 1 つのバイト配列比較は、publisherGuid (C#) と pPublisherId (C++) (GUID としての発行者 ID) です。私は彼らが再び一致すると思います。C#:

C# バイト配列

C++:

C++ バイト配列

値が暗号化された後に出力を見ると、違いがわかります。

C# では、次のコードから出力を取得します。

        var macObject = new HMACSHA256(anidBytes);
        var hashed = macObject.ComputeHash(publisherBytes);

バイト配列は次のようになります。

C# 暗号化の結果

C++ コードで、pUniqueId (BCryptFinishHash の結果) を確認すると、次のようになります。

C++ ハッシュ結果

どちらの場合も長さは同じように見えますが、結果は異なります。

C# で、エンコーディング タイプを UTF8 から Unicode に変更すると、anidBytes バイト配列は次のように変更されます。

ユニコード

したがって、C++ デバッガーが示すものと同じです。結果も変わりますが、それでも C++ とは異なります。新しい C# の結果は次のとおりです。

C# ユニコードの結果

これは C++ からの正しい結果です。

正しい結果

4

3 に答える 3