Skip to content

Safety Net

Safety Net

  • Used to verify genuine Android Device (Not Emulator)
  • Cryptographically signed request with information about the hardware and software.
  • Does not check if the device is rooted

Workflow

sequenceDiagram
Client App ->> Google Play Services : SafetyNet Attestation API receives a call from your app. This call includes a nonce.
Google Play Services ->> Google : SafetyNet Attestation service evaluates the runtime environment and requests a signed attestation of the assessment results from Google's servers.
Google ->> Google Play Services : Google's servers send the signed attestation to the SafetyNet Attestation service on the device.
Google Play Services ->> Client App : SafetyNet Attestation service returns this signed attestation to your app.
Client App ->> Client Server : Your app forwards the signed attestation to your server.
Client Server ->> Client App : This server validates the response and uses it for anti-abuse decisions. Your server communicates its findings to your app.

Requests To Google

https://android-developers.googleblog.com/2017/04/safetynet-attestation-building-block.html

POST https://www.googleapis.com/androidcheck/v1/attestations/attest?alt=PROTO&key=AIzaSyCnnVHfS_78KAuBxUYZ8u5P_tnMpNCGJXA

Example Protobuf:

[[
	{"data": "2b92d322e5edbaff3662d97b3bd0216d", "datatype": "Length-delimited", "subtype": "Binary"},
	{"data": "com.duosecurity.duomobile", "datatype": "Length-delimited", "subtype": "ASCII"},
	{"data": "97fcdbffc4f30cc3141a76d7179afb42974b7976d68eb0aa497c12e526526613", "datatype": "Length-delimited", "subtype": "Binary"},
	{"data": "2de4e157b348a563d126a3de0f7600bacfcc32d33bb90936034912f5a0569b22", "datatype": "Length-delimited", "subtype": "Binary"},
	{"data": "16089019", "datatype": "Varint"},
	[
		{"data": "1", "datatype": "Varint"},
		{"data": "1", "datatype": "Varint"}
	],
	{"data": "1556053190764", "datatype": "Varint"},
	{"data": "0", "datatype": "Varint"}
], {"data": "BASE64 DATA", "datatype": "Length-delimited", "subtype": "ASCII"} ]

Response from Google

  • ctsProfileMatch: If 'true', the device profile matches one of Google's listed devices.
  • basicIntegrity: If 'true', the device running the app likely hasn't been tampered with.
  • nonces: To match the response to its request.
  • timestampMs: To check how much time has passed since you made the request and you got the response. A delayed response may suggest suspicious activity.
  • apkPackageName, apkCertificateDigestSha256, apkDigestSha256: Provide information about the APK, which is used to verify the identity of the calling app. These parameters are absent if the API cannot reliably determine the APK information.

Example JSON data:

{
  "nonce": "R2Rra24fVm5xa2Mg",
  "timestampMs": 9860437986543,
  "apkPackageName": "com.package.name.of.requesting.app",
  "apkCertificateDigestSha256": ["base64 encoded, SHA-256 hash of the certificate used to sign requesting app"],
  "apkDigestSha256": "base64 encoded, SHA-256 hash of the app's APK",
  "ctsProfileMatch": true,
  "basicIntegrity": true,
}