> ## 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.

# Serviços de criptografia do jogador

> Saiba mais sobre segredos compartilhados do jogador, chaves públicas de título e payloads de registro criptografados com RSA do PlayFab, usados para proteger a criação de contas e as solicitações de login do cliente.

## Segredos compartilhados do jogador

Os segredos compartilhados do jogador são um novo tipo de chave pseudossecreta, compartilhada entre os clientes do jogo. Usando uma API, ela pode ser trocada pela chave RSA pública do título e pode ser usada para realizar o registro de contas.

Os títulos podem ter várias chaves compartilhadas do jogador e podem configurá-las e revogá-las à vontade, por meio das chamadas da API Admin [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).

Os segredos compartilhados do jogador devem ser incorporados aos respectivos clientes, pois não há APIs de cliente para recuperá-los, sejam autenticadas ou não.

## Chave pública do título

O segredo compartilhado do jogador é então enviado para [GetTitlePublicKey](xref:titleid.playfabapi.com.client.authentication.gettitlepublickey). Se a chave for válida, a API retornará uma matriz de bytes de blob RSA CSP codificada em Base 64 que pode criptografar 237 bytes de dados.

Todas as APIs que permitem a criação de contas agora aceitam o envio de uma solicitação de registro como um payload criptografado no campo `EncryptedRequest`.

<Note>
  Os campos padrão **`TitleId`**, **`InfoRequestParameters`** e **`CreateAccount`** *não* devem ser incluídos no payload criptografado.
</Note>

## Usando a chave pública do título para registrar

Veja a seguir um código de exemplo para registrar um jogador usando `LoginWithCustomID` e a chave pública do título.

```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);
```

## Segredo do jogador

Parte do novo sistema de registro é um novo campo chamado `PlayerSecret`. Se definido, ele permite assinar cabeçalhos de solicitação que são validados pelo servidor durante chamadas de API para todos os serviços, incluindo solicitações de login.

O segredo do jogador só pode ser definido *uma vez* por usuário por título. Um usuário com vários títulos no mesmo estúdio precisa definir o segredo do jogador para cada um deles.

Se o segredo do jogador ainda não tiver sido definido durante o registro, é possível defini-lo chamando [SetPlayerSecret](xref:titleid.playfabapi.com.client.authentication.setplayersecret). Há APIs de administrador e de servidor que permitem definir o segredo do jogador com um *novo* valor, mesmo que ele já tenha sido definido anteriormente.

<Note>
  Depois de definido, o segredo do jogador deve ser armazenado com segurança no dispositivo, pois ele *não* pode ser recuperado se for perdido e *não* existem APIs para recuperá-lo.
</Note>

## Usando o segredo do jogador para assinar solicitações de API

O exemplo de código a seguir constrói um cabeçalho de assinatura que pode ser usado para assinar solicitações de API. O formato do cabeçalho de assinatura é mostrado abaixo.

`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);
```

## Usando a imposição de políticas

As [Políticas de API](https://playfab.com/blog/permission-policies/) agora podem ser usadas para impor estes cenários.

* Uma solicitação do cliente é um payload criptografado.
* Uma solicitação do cliente contém cabeçalhos assinados.

Mesmo *sem* usar a imposição de políticas, se um payload criptografado for enviado (ou se os cabeçalhos forem enviados), eles serão validados. Se não estiverem formados corretamente, ocorrerá um erro.

Para criar uma política que exija cabeçalhos em uma API específica, use uma instrução `Deny`. Isso cria uma política que exige cabeçalhos em *todas* as chamadas que você pode fazer e que não são permitidas pela instrução `Allow`.

As instruções de política têm uma propriedade chamada `ApiConditions`. `ApiConditions` contém uma propriedade chamada `HasSignatureOrEncryption`, que é uma enumeração com três valores possíveis:

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

<Note>
  O padrão (se *não* for definido pela política) é **`Any`**.
</Note>

A política de exemplo a seguir permite *todas* as chamadas de API (exceto chamadas não criptografadas ou sem cabeçalhos) para `LoginWithCustomID`.

```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--*"
        }
    ]
}
```

A instrução `Deny` acima contém `HasSignatureOrEncryption: False`. Isso significa que todas as solicitações que não têm assinatura ou criptografia são rejeitadas. Em outras palavras, todas as solicitações que *têm* cabeçalhos de assinatura ou criptografia são permitidas com base na `Allow the rest policy`.


## Related topics

- [Autenticação dos serviços do XBOX para serviços de título](/pt-BR/services/xbox-services/fundamentals/s2s-auth-calls/service-authentication/live-title-service-authentication.md)
- [Modelo de criptografia do MSIXVC2](/pt-BR/build/core-features/common/packaging/packaging-encryption-msixvc2.md)
- [Tokens de segurança dos serviços do XBOX (tokens XSTS)](/pt-BR/services/xbox-services/fundamentals/s2s-auth-calls/service-authentication/security-tokens/live-security-tokens.md)
- [Uso dos privilégios de usuário dos serviços do XBOX no lado do cliente](/pt-BR/services/xbox-services/fundamentals/identity/privileges/concepts/live-user-privileges-client.md)
- [Visão geral dos Dados do jogador do XBOX](/pt-BR/services/xbox-services/player-data/live-playerdata-overview.md)
