Token Format

The token returned by the Windows Live ID service is encrypted. To perform the encryption, a signature key and an encryption key are derived from the secret key you specified during the application registration process. The token is first signed by using the signature key and then is encrypted by using the encryption key. The signature algorithm is HMAC-SHA256 and the encryption algorithm is AES128.

Bb676622.note(en-us,MSDN.10).gifImportant:
The Web Authentication application ID is 64 bits (or 8 bytes or 16 hexadecimal digits) long. The User ID is 128 bits (or 16 bytes or 32 hexadecimal digits) long.

To decrypt the token, an encryption key and a signature key are first generated as byte arrays from your secret key, as shown in the following example.

byte[] cryptKey = derive(secretKey, "ENCRYPTION");
byte[] signKey = derive(secretKey, "SIGNATURE");

In the preceding example, secretKey is the string value of your secret key. The derive function—for creating the encryption and signature keys from the secret key—is shown in the next example.

Bb676622.note(en-us,MSDN.10).gifImportant:
The sample code shown in this topic is simplified and error checking has been removed for readability. For the complete code, including error checking and try/catch blocks, please view the source code for the ProcessLogin method from the sample application for your platform.
static byte[] derive(string secret, string prefix)
{
    using(HashAlgorithm hashAlg = HashAlgorithm.Create("SHA256"))
    {
        const int keyLength = 16;
        byte[] data = Encoding.Default.GetBytes(prefix+secret);
        byte[] hashOutput = hashAlg.ComputeHash(data);
        byte[] byteKey = new byte[keyLength];
        Array.Copy(hashOutput, byteKey, keyLength);
        return byteKey;
    }
}

After the encryption and signature keys have been generated, the token is decoded as shown in the following example.

const int ivLength = 16;
token = HttpUtility.UrlDecode(token);
byte[] ivAndEncryptedValue = Convert.FromBase64String(token);
aesAlg = new RijndaelManaged();
aesAlg.KeySize = 128;
aesAlg.Key = cryptKey;
aesAlg.Padding = PaddingMode.PKCS7;
memStream = new MemoryStream(ivAndEncryptedValue);
byte[] iv = new byte[ivLength];
memStream.Read(iv, 0, ivLength);
aesAlg.IV = iv;
cStream = new CryptoStream(memStream, aesAlg.CreateDecryptor(), CryptoStreamMode.Read);
sReader = new StreamReader(cStream, Encoding.ASCII);
decodedValue = sReader.ReadToEnd();

After the token is decoded, the decodedValue variable contains a string in the following format.

appid=<application id>&uid=<unique identifier>&ts=<timestamp>&sig=<signature>[&flags=<flags>]

The following table describes the parameters contained within the decoded token.

Parameter Description

appid

The application ID.

uid

The user's unique identifier.

ts

A 32-bit integer representing seconds elapsed since Jan 1, 1970 GMT.

sig

HMAC-SHA256 signature using secret key. Base64 encoded.

flags

Optional. A 32-bit integer used to hold bit flags. If present, currently only bit 0 (the rightmost bit) is used. Bit 0 values indicate the following:

  • 0—Site must not store the user's token in a persistent cookie.
  • 1—Site may store the user's token in a persistent cookie.
See Also

Concepts

Response Parameters

Page view tracker