Securing 2M+ accounts & $15B+ in assets, protected & secure·B5 Secure™ — per data-element authorization for .NET platforms

Secure a Google Android App

Native client

Secure a Google Android App

The Android application should use user-bound, short-lived authority and hardware-backed key material where available. It must not embed a reusable tenant signing secret.

Integration path

Required controls

Implementation steps

Register the package name, signing certificate digest, app links, and environment ownership.
Use authorization code with PKCE and short-lived access tokens.
Create non-exportable keys in Android Keystore when the device supports them.
Validate Play Integrity responses on the server with request-bound nonces.
Apply policy using user, app, device, integrity, scope, and risk context.
Test rooted or compromised devices, reinstall, clock skew, offline mode, token theft, and revocation.

Control details

Pkce

Generate the verifier on-device for each authorization attempt and bind the redirect to an approved app link.

Keystore

Prefer hardware-backed and StrongBox-backed keys where supported, with explicit fallback policy.

Device Proof

Sign request-bound challenges using the registered device key and reject reused proofs.

Integrity

Treat Play Integrity as one server-verified signal. Bind verdicts to nonce, application, account, and freshness.

Google Android

Hardware-backed keys where available

Kotlin Keystore excerpt
package com.example.b5

import android.security.keystore.KeyGenParameterSpec
import android.security.keystore.KeyProperties
import java.security.KeyPairGenerator
import java.security.KeyStore
import java.security.Signature

object B5DeviceProof {
    private const val Alias = "b5-device-proof"

    fun ensureKey() {
        val store = KeyStore.getInstance("AndroidKeyStore").apply { load(null) }
        if (store.containsAlias(Alias)) return

        val generator = KeyPairGenerator.getInstance(
            KeyProperties.KEY_ALGORITHM_EC,
            "AndroidKeyStore"
        )
        generator.initialize(
            KeyGenParameterSpec.Builder(
                Alias,
                KeyProperties.PURPOSE_SIGN or KeyProperties.PURPOSE_VERIFY
            )
                .setDigests(KeyProperties.DIGEST_SHA256)
                .setUserAuthenticationRequired(false)
                .build()
        )
        generator.generateKeyPair()
    }

    fun sign(challenge: ByteArray): ByteArray {
        val store = KeyStore.getInstance("AndroidKeyStore").apply { load(null) }
        val privateKey = store.getKey(Alias, null) as java.security.PrivateKey
        return Signature.getInstance("SHA256withECDSA").run {
            initSign(privateKey)
            update(challenge)
            sign()
        }
    }
}

// Verify device proof and Play Integrity server-side. Never embed a tenant-wide secret.
  • Register package name, signing certificate digest, and app links.
  • Use authorization code with PKCE.
  • Prefer hardware-backed or StrongBox-backed keys when available.
  • Verify Play Integrity server-side with a request-bound nonce.
  • Test reinstall, rooted-device policy, token theft, and revocation.
Developer Relations

Talk to a human.

Get architecture guidance, Test Mode access, integration review, or help choosing the right B5 identity and authorization pattern.

Scroll to Top