Android fingerprinting

Using the Castle Android SDK to fingerprint Android app user devices

Summary

Fingerprinting is a core component of a Castle integration that enhances Castle’s ability to detect fraudulent and malicious abuse of in-application activity.


Steps

  1. Configure with API key
  2. Forward the fingerprint
  3. (optional) Additional configuration


Tutorial

Step 1. Configure with API key

Grab your Publishable API Key from the Castle Dashboard Settings Page and configure the SDK:

import io.castle.android.Castle;

// Place the below in your Application class onCreate method
Castle.configure(application, "{Publishable-API-Key}");

The Castle SDK collects fingerprint information from the device and sends this information directly to Castle. These requests are batched to optimize device performance. See the last section, Configuration Notes, to make changes to the way Castle collects and batch-processes this fingerprint information.

Step 2. Forward the fingerprint

The Castle Android SDK generates a value that we call the client_id. Forward the Castle client_id in relevant requests to your application server.

The client_id value contains a proprietary signature of the mobile device fingerprint. This value should not be used as an identifier. It should be treated as a token. The value will change over time.

You will need to forward the client identifier as a request header to every request to your API. This header will then be parsed by the Castle server-side SDK. You can specify this header name in the SDK configuration. The default value (recommended) is X-Castle-Client-Id.

// OkHttp
requestBuilder.header(
    Castle.clientIdHeaderName,
    Castle.clientId();
);

// HttpURLConnection
httpUrlConnection.setRequestProperty(
    Castle.clientIdHeaderName,
    Castle.clientId();
);

// Volley
headers.put(
    Castle.clientIdHeaderName,
    Castle.clientId();
);

then, from the application server (this code results in an error for invalid ip - it is meant for reference only):

curl -s https://api.castle.io/v1/authenticate \
  -X POST \
  -u ":$SECRET" \
  -H "Content-Type: application/json" \
  -d '
  {
    "event": "$login.succeeded",
    "user_id": "{user_id}",
    "user_traits": {
      "email": "{user_email}"
    },
    "context": {
      "client_id": "{castle_client_id}",
      "ip": "{ip}",
      "headers": {
        "User-Agent": "{User-Agent}"
      }
    }
  }' | json_pp

Step 3. (optional) Additional configuration

  • The SDK allows for additional configuration options. Please refer to the documentation packaged with the SDK code for full details.
ArrayList<String> baseUrlWhiteList = new ArrayList<>();
baseUrlWhiteList.add("https://api.example.com/");

CastleConfiguration configuration = new CastleConfiguration.Builder()
  .publishableKey("{Publishable-API-Key}")
    .screenTrackingEnabled(true) // Default true
    .debugLoggingEnabled(true) // Default false
    .flushLimit(10) // Default 20
  .baseURLWhiteList(baseUrlWhiteList)
  .maxQueueLimit(100) // Default 1000
  .build();

// Setup Castle SDK with provided configuration
Castle.configure(application, configuration);

Configuration notes

Queue flushing

The SDK queues API calls to save battery life, and it only flushes queued events to the Castle API whenever the app is installed, updated, opened or closed; when identify is called; or when the queue reaches 20 events. This ensures that the device fingerprint is fully profiled before any requests to your server side.

Automatic screen tracking

When automatic screen tracking is enabled any activities or view controllers shown will automatically generate a screen event. The screen name will use a normalized version of the activities or view controllers title. For more granular control we suggest disabling automatic screen tracking (on by default) and calling screen manually.