View Source ExUid2
A library to interact with Unified ID2
It currently only handles the DSP part of UID2 (decrypting UID2 tokens in bid requests).
Installation
Add :ex_uid2 to the list of dependencies in mix.exs
def deps do
[
{:ex_uid2, "~> 0.1.0"}
]
end
Usage
Add the ExUid2 configuration to your application's config file:
import Config
config :ex_uid2,
base_url: "https://uid2_operator_server.com",
api_key: "your_api_key",
secret_key: "your_secret_key"
Once started, the application will periodically request a fresh keyring from the configured UID2 operator server. Encrypted tokens can then be decrypted.
ExUid2.Dsp.decrypt_token(<redacted>)
{:ok,
%ExUid2.Uid2{
uid: <redacted>,
established: ~U[2024-07-02 01:17:56.501Z],
site_id: 11,
site_key: %ExUid2.Keyring.Key{
activates: 1717269873,
created: 1717183473,
expires: 1725909873,
id: 2383,
secret: <redacted>,
keyset_id: nil
},
identity_scope: "UID2",
identity_type: nil,
advertising_token_version: 2,
expires: ~U[2024-07-06 19:12:10.313Z]
}}
If the keyring hasn't been properly fetched by the time a token decryption is attempted, an error tuple will be returned instead:
ExUid2.Dsp.decrypt_token(<redacted>)
{:error, :no_keyring_stored}
Token decryption specification
Since no specification for the token decryption protocol could be found, the decryption protocol has been found by reverse engineering the existing SDKs and may include errors and misconceptions, so this specification may be erroneous or incomplete, but has been shown to work for decoding encrypted UID2 tokens.
General flow
- A keyring is periocically updated by querying the
/v2/key/sharing
endpoint. - The encrypted token envelope is fetched from the bid request
- The envelope is parsed to extract the token version, the master key ID, the master IV and the master payload
- The right key to decrypt the master payload is obtained by looking up the master key ID in the keyring.
- The master payload is decrypted using AES-256-CBC, the master key and the master IV.
- The decrypted master payload is parsed to extract the expiration timestamp, the site key ID, the identity IV and the identity payload.
- The expiration timestamp is checked to ensure the token is still valid.
- The right key to decrypt the identity is obtained by looking up the site key ID in the keyring.
- The indentity payload is decrypted using AES-256-CBC, the site key and the identity IV.
- The decrypted identity payload is parsed to extract the site ID, the identity length, the identity binary and the established timestamp.
/v2/key/sharing
request
While the /v2/key/sharing
endpoint is undocumented, The workflow to query UID2's endpoints is documented, the
Encrypting Requests and Decrypting Responses documentation seem to apply there. It is what
this library is doing.
Encrypted token envelope
Offset (bytes) | Size (bytes) | Description |
---|---|---|
0 | 1 | UID2 token version |
1 | 4 | Master key ID. Must be uint32 big endian. |
5 | 16 | Master 128-bit initialization vector (IV), which is used to randomize data encryption. |
21 | N | Master Payload (encrypted) |
Decrypted Master Payload
Offset (bytes) | Size (bytes) | Description |
---|---|---|
0 | 8 | Expiration time in milliseconds (Unix timestamp). Must be uint64 big endian. |
8 | 4 | Site key ID. Must be uint32 big endian. |
12 | 16 | Identity 128-bit initialization vector (IV), which is used to randomize data encryption. |
| 28 | N | Identity Payload (encrypted)
Decrypted Identity
Offset (bytes) | Size (bytes) | Description |
---|---|---|
0 | 4 | Site ID. Must be uint32 big endian. |
4 | 4 | Length in bytes of ID binary. Must be uint32 big endian. |
8 | N | Base64-encoded ID binary (the actual user ID). |
8 + N | 4 | Unknown. |
12 + N | 8 | Time when the identity was established in milliseconds (Unix timestamp). Must be uint64 big endian. |
20 + N | M | Unknown. |