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++ を知らないので、これら 2 つが同一かどうかはわかりません。それらはそうですが、C++ にはそれぞれの後にこれらの '\0' 文字があり、それで問題ないかどうかわかりません。どちらの場合も長さは 44 と報告されているので、そうだと思います。
もう 1 つのバイト配列比較は、publisherGuid (C#) と pPublisherId (C++) (GUID としての発行者 ID) です。私は彼らが再び一致すると思います。C#:
C++:
値が暗号化された後に出力を見ると、違いがわかります。
C# では、次のコードから出力を取得します。
var macObject = new HMACSHA256(anidBytes);
var hashed = macObject.ComputeHash(publisherBytes);
バイト配列は次のようになります。
C++ コードで、pUniqueId (BCryptFinishHash の結果) を確認すると、次のようになります。
どちらの場合も長さは同じように見えますが、結果は異なります。
C# で、エンコーディング タイプを UTF8 から Unicode に変更すると、anidBytes バイト配列は次のように変更されます。
したがって、C++ デバッガーが示すものと同じです。結果も変わりますが、それでも C++ とは異なります。新しい C# の結果は次のとおりです。
これは C++ からの正しい結果です。