Example token
Splitting and handling the outer token
The various sections of the token can be broken up as follows.Outer token header
So, for example, the header component is:0004A3A12C1D5E59307A308D6D02E83978E2A9AE, which you can get by using Base64URL to decode the x5t value.
AASjoSwdXlkwejCNbQLoOXjiqa4 -> Base64Url decode to byte array -> [ 00-04-A3-A1-2C-1D-5E-59-30-7A-30-8D-6D-02-E8-39-78-E2-A9-AE ]
-> Convert into a string and remove the '-' characters
Decrypting the content encryption key (CEK)
Using the private key of the Relying Party certificate that matches the thumbprint, we can then decrypt the Content Encryption Key (CEK):Getting the HMAC, AES, and IV (initialization vector) to decrypt the payload
The CEK can then be broken into thehmacKey and the aesKey.
The HMAC key is the first half of the CEK with the AES key as the second half.
Decrypting the payload
With the above keys we can now decrypt the payload of the outer token to the following. For the code that is doing this decryption please see theDecryptAsync and Decrypt APIs in XstsUtilities.cs of the Game Service sample.
DecompressAsync in XstsUtilities.cs of the Game Service sample.
Handling the decrypted inner token
After decompressing the decrypted byte array of the outer token payload, we now have a standard JSON Web Token (JWT) that houses the claims and information that contains the claims for the user, title, and device as defined in the relying party.Validating the inner token
To validate the inner token’s contents, your service should validate the signature of the JWT following the standard defined in JWT RFC 7516. This example token is configured for JKU signature validation in Partner Center, so the header of the inner token gives us the following:kid value identifies the specific XBOX Live signing key used to generate the signature.
The jku value points to a URL where the public key can be downloaded and used to validate the signature.
If the domain name of the jku is not “xsts-keys.auth.xboxlive.com”, then the token should not be trusted.
It is recommended to cache they key at runtime as the signing keys change frequently.
This also allows your service to be resilient and able to handle obtaining new keys when they are updated on the fly without downtime or maintenance.
If you are using an existing JWT open-source solution, signature validation is done automatically when you pass in the JKW public key to the JWK decoding API.
After validating the signature, your service can trust that the certificate and the data within it are authentic.
For more information on the inner token validation for both the XBOX Live signing JWK and XBOX Live signing certificate, see Inner token header and signature validation
Identifying the correct user in the token
Tokens will have user identities for all XBOX Live users who are actively signed-in at the time the token was created on the client. Therefore, your service needs to use the user hash value from the HTTP authorization header, and find the matchingush value within the user identities.
For this example token the Authorization header had a user hash of 18026470712427541036.
From this we can see the claims are there for this user hash who is Gamertag 2 Dev 079574836.
Although this token only has one user identity in the token claims, we shouls still validate that it matches the user hash from the header.
