How to Combine AppiCrypt and Play Integrity (Pt. 3/3)
AppiCrypt and Play Integrity are complementary products with a small overlap, but a big advantages on the side of AppiCrypt stemming from RASP+ core. Let's learn how to bind both to one API request.
⚡Key takeaways:
🔗 Verifying two security verdicts independently or binding them to the same request gains you a best of both them.
🧬 They answer different questions. AppiCrypt: what is happening inside this runtime, on this request, right now? Play Integrity: what does Google think of this device and this install?
🚫 Binding kills mix-and-match — pairing a Play Integrity token minted on a compromised device with a cryptogram from a clean one. Both bring different security claims. The pair has them all.
⚖️ Disagreement is a welcome. "Google says OK, the Talsec says hooking attack"
💰 Order your checks cheapest-first. Verify AppiCrypt before you spend Play Integrity quota💬
The full wire format and verification algorithm ship as a blueprint with AppiCrypt. Questions about your own endpoints? info@talsec.app

AppiCrypt + Play Integrity Binding: The Design
The two mechanisms have different coverage and different failure modes. Verifying them independently gains little: you learn two facts that were already available separately. What you gain by binding them is something neither has on its own.

Binding value
A URL-safe base64 string passed to both attestation producers, tying two independent verdicts to one request.
Challenge
A server-issued, single-use random value contributed to the binding value. Optional in general, required for sensitive endpoints.
Attestation pair
One AppiCrypt cryptogram and one Play Integrity token carrying the same binding value.
Absence
No Play Integrity token was supplied, or it could not be decoded, for reasons outside the caller's control. Not the same as a negative verdict.
Side by side
AppiCrypt®
Play Integrity
Root of trust
Talsec SDK, in your app
Google Play services
Platforms
iOS, Android, Web — no GMS dependency
Android with Google Play services only
Availability
offline-capable, no quota
needs network + Play, 10k/day default quota
Cadence
every API request
per session, or per sensitive action
Tells you
root, jailbreak, hooking, debugger, emulator, repackaging, tampering — what is happening in the runtime right now
unrecognised binary, uncertified device, unlicensed install, Play Protect state — what Google thinks of this device
Who verifies
your backend
Google, then your backend
Fails when
your SDK integration is wrong
Google is down, quota is exhausted, or the device has no Play services
Where they overlap
Genuine overlap exists (unless spoofed):
App identity. Both can tell you which package and which signing certificate you are talking to.
Basic device compromise. A simply modified device will often — not always — fail both.
Install source. Play Integrity knows whether the install came from Play. AppiCrypt sees the repackaging and tampering that frequently accompany an unofficial one.
Where they overlap, they are a cross-check. Where they do not, they are genuine coverage.
Where they complement
Cadence. Play Integrity's quota makes per-request attestation impossible at any real scale. AppiCrypt has no quota, so every call can carry proof. Between them: continuous proof plus a periodic second opinion.
Runtime versus reputation. A device can be perfectly stock, fully certified, licensed — and have Frida attached right now. Play Integrity may fail while AppiCrypt provides the real visibility into the device.
Platform support. iOS and Web have no Play Integrity at all. One mental model and one backend code path across all three beats maintaining Play Integrity on Android and App Attest on iOS with different semantics to reconcile.
Ownership. AppiCrypt lives entirely in infrastructure you control. When the Play Integrity server is down, you still have a decision you can build on.
Protocol overview
Walking it through:
Challenge (optional in general, required for anything that moves money or state). The backend issues a single-use random value with a TTL. Without one, the same payload always produces the same binding — so a captured attestation pair replays until it ages out. A payload-only binding proves which request the attestations belong to, but not when.
Derive the binding value from the challenge and the exact bytes of the request body.
Ask both producers for an attestation, in parallel, passing the identical string. Warm up the Play Integrity token provider outside the request path — at app start, or on entering the flow. Never pay that latency per request.
Send one request carrying the payload and both attestations. They travel in headers, not in the payload, so the body remains exactly the bytes that were hashed.
Verify cheapest-first. Structural checks, re-derive the expected binding, verify AppiCrypt — and only then exchange the Play Integrity token with Google. A request that fails early costs no quota.
Cross-check and decide. Compare the overlapping claims. Any contradiction denies. Then: allow, step up, or deny.
The full blueprint
What this article gives you is the generic composition: why the two belong together, what the binding value is for, and the order the checks go in. That is enough to decide whether the model fits your architecture.
What it deliberately does not reproduce is the specification — the exact wire format and header contract, the canonical binding construction, the complete backend verification algorithm, the per-field rules for identity and freshness, the absence-handling policy, and the full cross-verdict denial matrix.
That blueprint is shipped as part of the AppiCrypt® product — so you can simply implement it rather than rediscover it.
Write to info@talsec.app and we will walk your flow with you.
AppiCrypt® — cryptographic proof of app and device integrity on every API call, verified by your own backend (Android & iOS)
AppiCrypt for Web — the same protocol in the browser
RASP+ — the runtime signals the cryptogram carries: root, hooking, debugger, emulator, tampering and more
Plans Comparison
Last updated
Was this helpful?

