> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Player Encryption サービス

> アカウント作成とクライアント ログイン要求を保護するために使用される、PlayFab の Player Shared Secret、タイトル公開キー、RSA 暗号化された登録ペイロードについて説明します。

## Player Shared Secret

Player Shared Secret は、ゲーム クライアント間で共有される新しい種類の擬似シークレット キーです。API を使うと、タイトルの RSA 公開キーと交換でき、アカウント登録の実行に使用できます。

タイトルは複数の Player Shared Key を持つことができ、Admin API 呼び出し ([Create](xref:titleid.playfabapi.com.admin.authentication.createplayersharedsecret)、[Update](xref:titleid.playfabapi.com.admin.authentication.updateplayersharedsecret)、[Delete](xref:titleid.playfabapi.com.admin.authentication.deleteplayersharedsecret)、[List](xref:titleid.playfabapi.com.admin.authentication.getplayersharedsecrets)) を介して、必要に応じて設定・取り消しできます。

Player Shared Secret は、認証されているか否かを問わず、それらを取得するクライアント API が存在しないため、それぞれのクライアントに組み込んでおく必要があります。

## タイトル公開キー

Player Shared Secret は [GetTitlePublicKey](xref:titleid.playfabapi.com.client.authentication.gettitlepublickey) に送信されます。キーが有効であれば、この API は 237 バイトのデータを暗号化できる Base 64 エンコードされた RSA CSP blob バイト配列を返します。

アカウント作成を許可するすべての API は、登録要求を暗号化ペイロードとして `EncryptedRequest` フィールドに投稿することを受け入れるようになりました。

<Note>
  標準フィールドである **`TitleId`**、**`InfoRequestParameters`**、および **`CreateAccount`** は、暗号化ペイロードに含めるべきでは *ありません*。
</Note>

## タイトル公開キーを使用した登録

`LoginWithCustomID` とタイトル公開キーを使用してプレイヤーを登録するサンプル コードを次に示します。

```csharp theme={null}
var titleKeyResult = PlayFabClientAPI.GetTitlePublicKey(new GetTitlePublicKeyRequest{ TitleId = "TITLE", TitleSharedSecret = "player shared secret" });

var cspBlob = Convert.FromBase64String(titleKeyResult.RSAPublicKey);

var encryptionModel = JsonConvert.SearializeObject(new LoginWithCustomIDRequest

{
    CustomID = "my player's custom id",
    PlayerSecret = "my player's individual secret"
});

string encryptedPayload;

using (var rsa = new RSACryptoServiceProvider())
{
    rsa.ImportCspBlob(cspBlob);
    var bytesToEncrypt = Encoding.UTF8.GetBytes(encryptionModel);
    var encryptedBytes = rsa.Encrypt(bytesToEncrypt, false);
    encryptedPayload = Convert.ToBase64String(encryptedBytes);
}

var postModel = new LoginWithCustomIDRequest
{
    TitleId = "TITLEID",
    EncryptedRequest = encryptedPayload,
    CreateAccount = True
};

var createAccountResult = PlayFabClientAPI.LoginWithCustomID(postModel);
```

## Player Secret

新しい登録システムの一部として、`PlayerSecret` という新しいフィールドがあります。設定されている場合、ログイン要求を含むすべてのサービスへの API 呼び出し中に、サーバーによって検証されるリクエスト ヘッダーに署名できます。

Player Secret は、タイトルごとにユーザーごとに *1 回のみ* 設定できます。同じスタジオ内で複数のタイトルを持つユーザーは、各タイトルに対して Player Secret を設定する必要があります。

Player Secret が登録時にまだ設定されていない場合は、[SetPlayerSecret](xref:titleid.playfabapi.com.client.authentication.setplayersecret) を呼び出して設定できます。以前に設定されていても、Player Secret を *新しい* 値に設定できる admin および server API があります。

<Note>
  一度設定した Player Secret は、失うと復元 *できません* し、それを回復する API も *存在しない* ため、デバイスに安全に保存する必要があります。
</Note>

## Player Secret を使用した API リクエストへの署名

以下のコード例では、API リクエストの署名に使用できる署名ヘッダーを構築します。署名ヘッダーの形式は次のとおりです。

`jsonRequestModel.utcTimeStampInISO.playerSecret`

```csharp theme={null}
var postModel = new LoginWithCustomIDRequest

{
    TitleId = "TITLEID",
    CustomID =  "my player's custom id",
    CreateAccount = False
};

string signatureHeader;
string timestampHeader = DateTime.UtcNow.ToString("O");

string playerSecret; // the player secret that was sent during registration.

 using (var hash = new SHA256Managed())
{
    var bytesToHash = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(postModel)+"." + timestampHeader + "." + playerSecret);
    signatureHeader = hash.ComputeHash(bytesToHash);
}

var customHeaders = new Dictionary<string, string>
{
    { "X-PlayFab-Signature", signatureHeader },
    { "X-PlayFab-Timestamp", timestampHeader }
}

var loginResult = PLayFabClientAPI.LoginWithCustomID(postModel, customHeaders);
```

## ポリシー適用の使用

[API ポリシー](https://playfab.com/blog/permission-policies/) を使用して、これらのシナリオを適用できるようになりました。

* クライアント要求が暗号化ペイロードであること。
* クライアント要求に署名付きヘッダーが含まれていること。

ポリシー適用を使用しない *場合でも*、暗号化されたペイロード (またはヘッダー) が送信されると、それらは検証されます。適切な形式でない場合、エラーが発生します。

特定の API でヘッダーを必須とするポリシーを作成するには、`Deny` ステートメントを使用します。これは、`Allow` ステートメントで許可されていないすべての呼び出しでヘッダーを必須とするポリシーを作成します。

ポリシー ステートメントには `ApiConditions` というプロパティがあります。`ApiConditions` には `HasSignatureOrEncryption` というプロパティが含まれ、これは 3 つの可能な値を持つ列挙型です。

* `Any`
* `True`
* `False`

<Note>
  既定値 (ポリシーで設定されていない場合) は **`Any`** です。
</Note>

以下の例のポリシーでは、`LoginWithCustomID` へのすべての API 呼び出しを (暗号化されていない、またはヘッダーが欠けている呼び出しを除いて) 許可します。

```json theme={null}
{
    "PolicyName": "ApiPolicy",
    "OverwritePolicy": true,
    "Statements":
    [
        {
            "Comment": "Require Headers on LoginWithCustomID",
            "Action": "*",
            "Principal": "*",
            "Effect": "Deny",
            "Resource": "pfrn:api--/Client/LoginWithCustomID",
            "ApiConditions": { "HasSignatureOrEncryption": "False" }
        },
        {
            "Comment": "Allow the rest policy",
            "Action": "*",
            "Principal": "*",
            "Effect": "Allow",
            "Resource": "pfrn:api--*"
        }
    ]
}
```

上記の `Deny` ステートメントには `HasSignatureOrEncryption: False` が含まれています。これは、署名または暗号化がないすべての要求が拒否されることを意味します。言い換えれば、署名ヘッダーまたは暗号化が *ある* すべての要求は、`Allow the rest policy` に基づいて許可されます。


## Related topics

- [Web サービス](/ja-jp/services/xbox-services/fundamentals/s2s-auth-calls/custom-service-config/web-services/index.md)
- [XBOX サービス向けツール](/ja-jp/tools/tools-services/live-tools-nav.md)
- [XBOX サービスの構成](/ja-jp/publishing/game-publishing/concepts/xbox-services.md)
- [オプション サービス](/ja-jp/build/gdk-and-engines/optional-services.md)
- [サービス認証](/ja-jp/services/xbox-services/fundamentals/s2s-auth-calls/service-authentication/index.md)
