Mobile App Setup

Mobile App Fraud Prevention

Keyri offers best in class mobile fingerprinting and device integrity verification, accessible in as little as one line of code.

The SDK will:

  • Generate a unique fingerprint which persists even when the app is deleted This is something many developers struggle with. It's quite easy to keep a fingerprint UNTIL the app is deleted, but persistence across installations is tricky. This is exacerbated by the ease with which bad actors can clear out records in the iOS Keychain or Android Secure Storage.
  • Send the information to our API using a strong cryptography technique which ensures the information cannot be tampered with or intercepted Note: This information will be available on the Keyri Dashboard
  • Verify device integrity to stop bad actors in their tracks. We have checks to protect against
    • Jailbreaks
    • Malicious sideloaded applications
    • Method swizzling
    • Code tampering
    • Emulators
    • Optional protection against:
      • VPN
      • Blocklist usage
      • TOR

Requirements

  • iOS: iOS 14+
  • Android: API Level 23

Implementation and Installation

Methods

  • generateAssociationKey(publicUserId: String) -> P256.Signing.PublicKey: Create a persistent (even on app deletion) record of a user
  • getAssociationKey(publicUserId: String) -> P256.Signing.PublicKey?: Retrieve key for a given user, if the user has been created
  • listAssociationKeys() -> [String: p256Key]: List the accounts that have been created
  • generateUserSignature(publicUserId: String, data: Data) -> P256.Signing.ECDSASignature: Sign a piece of data with the user's key
  • sendEvent(publicUserId: String, eventType: EventType, success: Bool) -> FingerprintResponse: Send Keyri a fingerprint of the device

Example: Protecting Registration/Signup

The following example protects your registration/signup flow. Regardless of the credentials that the user inputs when trying to create a new account (like a new username), the Keyri methods included here will detect whether that device has already registered an account, and if so, suggest to the user to log in with that existing account rather than create a new one. Of course, you can implement other logic like allowing up to two accounts, blocking certain accounts altogether, etc. All you're getting when running listUniqueAccounts() is a useful, reliable array of accounts associated with that device, and you can parse and act upon it however you'd like.

func registerUser(username: String) throws {
    let keyri = KeyriInterface(appKey: appKey)
 
    if let list = keyri.listAssociationKeys() {
        if let existingUsername = list.keys.first {
            // Alert user that there is an existing user, and encourage them to sign in here
        }
    } else {
       let key = try keyri.generateAssociationKey(publicUserId: username)
       // Then run your regular registration process
       // Optionally, do something else with the key that just got generated.
       // Keyri Handles saving the key in the Secure Enclave for you
       // For example, you can later use this key pair to passwordlessly authenticate the user
    }
}

Example: Full Serverside Fingerprinting

func createUser(username: String) -> P256.Signing.PublicKey? {
    let keyri = KeyriInterface(appKey: appKey, publicApiKey: publicApiKey, serviceEncryptionKey: serviceEncryptionKey)
 
	if keyri.listAssociationKeys().count < MAX_ACCOUNT_LIMIT {
	    let key = keyri.generateAssociationKey(username: username)
 
	    // Optionally sign custom data with the key at this stage
		// remember, the key can always be retrieved with getAssociationKey
        keyri.sendEvent(publicUserId: username, eventType: EventType.login, success: true)
		return key
	} else {
		// Alert user that they’re exceeding the limit here
		return nil
	}
}

Android Accounts Backup

Preserving user-device fingerprints even after your app is deleted and re-installed requires additional backup configuration steps. This document will help you set up your account backup configuration.

You can find a comparison of Key/Value Backup and Auto Backup here: Android Backup Overview (opens in a new tab).

Keyri backup file keyri_backup_prefs is a SharedPreferences file that contains Keyri accounts. You need to keep this file after app uninstall to prevent a loss of accounts. There are two options for how to do it.

Android Auto Backup

Auto Backup for Apps automatically backs up a user's data from apps that target and run on Android 6.0 (API level 23) or higher.

Make sure that backup is not disabled in your application. allowBackup should not be false. The default value is true but to make your intentions clear, we recommend explicitly setting the attribute in your manifest as shown below:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application android:allowBackup="true">
        ...
    </application>
</manifest>

(opens in a new tab)Control backup on Android 11 and lower

Follow the steps in this section to include or exclude files that are backed up on devices running Android 11 (API level 30) or lower.

  1. In AndroidManifest.xml, add the android:fullBackupContent attribute to the <application> element. This attribute points to an XML file that contains backup rules. For example:
<application android:fullBackupContent="@xml/backup_rules">
    ...
</application>
  1. Create an XML file called @xml/backup_rules in the res/xml/ directory. Inside the file, add rules with the <include> and <exclude> elements. The following sample backs up all shared preferences except device.xml:
<?xml version="1.0" encoding="utf-8"?>
<full-backup-content>
    <include domain="sharedpref" path="." />
    <exclude domain="sharedpref" path="device.xml" />
</full-backup-content>

If you have more granular control over sharedPref backups, make sure you have included an keyri_backup_prefs.xml file.

(opens in a new tab)

Control backup on Android 12 or higher

If your app targets Android 12 (API level 31) or higher, follow the steps in this section to include or exclude files that are backed up on devices that are running Android 12 or higher.

  1. In AndroidManifest.xml, add the android:dataExtractionRules attribute to the <application> element. This attribute points to an XML file that contains backup rules. For example:
<application android:dataExtractionRules="backup_rules.xml">
    ...
</application>
  1. Create an XML file called backup_rules.xml in the res/xml/ directory. Inside the file, add rules with the <include> and <exclude> elements. The following sample backs up all shared preferences except device.xml:
<?xml version="1.0" encoding="utf-8"?>
<data-extraction-rules>
    <cloud-backup>
        <include domain="sharedpref" path="." />
        <exclude domain="sharedpref" path="device.xml" />
    </cloud-backup>
</data-extraction-rules>

If you have more granular control over sharedPref backups, make sure you have include keyri_backup_prefs.xml file.

Check for more details on Back up user data with Auto Backup (opens in a new tab).

Key/Value Backup (Android Backup Service)

Android Backup Service provides cloud storage backup and restore for key-value data in your Android app. During a key-value backup operation, the app's backup data is passed to the device's backup transport. If the device is using the default Google backup transport, then the data is passed to Android Backup Service for archiving. Data is limited to 5MB per user of your app. There is no charge for storing backup data.

Note: Key-value backup requires you to write code to define your backup content explicitly, while Auto Backup requires no code and will back up entire files. Most apps should use Auto Backup to implement backup and restore. Your app can implement Auto Backup or key-value backup, but not both.

(opens in a new tab)Implement key-value backup

To back up your app data, you need to implement a backup agent. Your backup agent is called by the Backup Manager both during backup and restore.

To implement a backup agent, you must:

  1. Declare your backup agent in your manifest file with the android:backupAgent attribute.

  2. Define a backup agent by doing one of the following:

  • Extending BackupAgent The BackupAgent class provides the central interface that your app uses to communicate with the Backup Manager. If you extend this class directly, you must override onBackup() and onRestore() to handle the backup and restore operations for your data.

  • Extending BackupAgentHelper The BackupAgentHelper class provides a convenient wrapper around the BackupAgent class, minimizing the amount of code you need to write. In your BackupAgentHelper, you must use one or more helper objects, which automatically back up and restore certain types of data, so that you don't need to implement onBackup() and onRestore(). Unless you need full control over your app's backups, we recommend using the BackupAgentHelper to handle your app's backups.

Android currently provides backup helpers that will back up and restore complete files from SharedPreferences and internal storage.

You can implement your own backup according to the documentation: Back up key-value pairs with Android Backup Service (opens in a new tab). In this case just include keyri_backup_prefs string to your BackupAgentHelper as shown below:

class MyBackupAgent : BackupAgentHelper() {
 
    override fun onCreate() {
        val helper = SharedPreferencesBackupHelper(this, "your prefs files (optional)", "keyri_backup_prefs")
 
        addHelper("YOUR BACKUP KEY", helper)
    }
}

After it just add your MyBackupAgent to AndroidManifest.xml:

<manifest>
    ...
    <application android:backupAgent="MyBackupAgent">
        <activity>
            ...
        </activity>
    </application>
</manifest>

Or you can just use our KeyriPrefsBackupAgent (opens in a new tab) which implements the necessary logic under the hood as shown below:

<manifest>
    ...
    <application android:backupAgent="com.keyrico.keyrisdk.backup.KeyriPrefsBackupAgent">
        <activity>
            ...
        </activity>
    </application>
</manifest>

Testing backup

See Test backup and restore (opens in a new tab) to test backup of Keyri accounts.

Privacy Disclosures

When submitting your Android app that uses the Keyri SDK for fingerprinting, be sure to disclose the following data collection practice:

Data TypesCollectedSharedProcessed ephemerallyRequired or OptionalPurposes
Device or other IDsYesYesNoRequiredAnalytics

An analogous disclosure is not required for iOS apps, since the device data is not used by Keyri for cross-app tracking.