Nov 14

10 things you might be doing wrong when using the SafetyNet Attestation API

Posted by Oscar Rodriguez, Developer Advocate

SafetyNet Attestation API helps you assess the security and compatibility of
the Android environments in which your apps run. Since it was introduced in
March 2015, many developers have successfully integrated it into their Android
apps to make more informed decisions based on the integrity and compatibility of
the devices running their apps.

Throughout the years, the SafetyNet Attestation API has evolved, and its
adoption has steadily increased. However, as with any security/anti-abuse
related API, there are many common pitfalls that may lead developers into
developing unstable systems, or worse, into a false sense of security.

In this post, we provide a list of the most common mistakes we have seen
developers make when integrating the SafetyNet Attestation API.

1. Not getting an API key

Just like many other Google APIs, the SafetyNet Attestation API requires an API
key in order to run. Furthermore, the SafetyNet Attestation API has a per-key
usage quota. Although you can get this quota increased, you need to provide your
API key to do so.

Getting an API key is easy and free of charge. There is no reason not to get an
API key, so if you haven’t already, get
an API key now.

2. Not using the latest version of the API

The SafetyNet Attestation API has evolved throughout its history, and with it,
there have been some interface changes. Most recently, with the release of
Google Play services 11.0.0, we revamped the entire SafetyNet API to offer an
interface that is easier and more streamlined to use: the new API uses SafetyNetClient
instead of SafetyNetApi,
which is now deprecated, so make sure you update your implementation to use the
latest version of the API.

Most devices should have the latest version of Google Play services installed,
but if a device doesn’t have Google Play services installed, or doesn’t have it
up to date, using the SafetyNet Attestation API may lead to the app becoming
unresponsive or crashing. You can prevent this by checking
the installed version of Google Play services before using the API.

3. Using nonces incorrectly

The SafetyNet Attestation API lets you set a nonce to uniquely and globally
identify each call to the API. Use this feature to prevent a malicious user from
reusing a successful attestation result in place of an unsuccessful result (also
known as a Replay

good way to create a nonce is to create a large (16 bytes or longer) random
number on your server using a cryptographically-secure random function. The
SafetyNet attestation response includes the nonce you set, so make sure you
verify that the returned nonce matches the one you included in the request you

4. Not checking the results on your server

SafetyNet can provide useful signals about the state of the device in which your
app is running. However, if the logic that acts on these signals is only
implemented and enforced directly on the device, an attacker could be able to
modify your app and bypass any checks you perform.

To prevent this situation, you should run any logic that verifies the
attestation result and enforces any actions based on them on a server that you
control and trust.

5. Using the test attestation verification service for production

In order to simplify development and testing of the SafetyNet Attestation API,
Google offers an online
verification service that checks the digital signature of a SafetyNet
Attestation result using a simple HTTPS request.

As useful as this service may seem, it is designed for test purposes only, and
it has very strict usage quotas that will not be increased upon request.
Instead, you should implement the digital signature verification logic on your
server in a way that it doesn’t depend on Google’s servers. Most JWT libraries
offer signature verification functionality, and we have code samples
that show how to perform this verification in Java and C#. We plan to provide
samples for more languages in the future.

6. Not checking the nonce, timestamp, APK name, and hashes

The SafetyNet Attestation API is most widely known for its integrity and
compatibility checks, whose results are returned in ctsProfileMatch
and basicIntegrity. Although these two values are indeed very
useful, you should check the other values in the response, as they contain
important information as well.

Use nonce to match a response to its request,
as explained above, and use timestampMs to check how much time has passed since you made the
request and you got the response. A delayed response that arrives several hours
or days after the request may suggest suspicious activity.

Use apkPackageName to check the name of the APK that made the
attestation request, and match apkDigestSha256 and
apkCertificateDigestSha256 to those from your app’s signed APK in
Google Play, to get a signal about the integrity of the installed app.

Remember that the trustworthiness of the response as a whole is tied to the
results of ctsProfileMatch and basicIntegrity. It is
not unthinkable for a compromised device that fails basicIntegrity
to have forged the rest of the values in the response.

7. Not understanding the differences between ctsProfileMatch
and basicIntegrity

The SafetyNet Attestation API initially provided a single value called
basicIntegrity to help developers determine the integrity of a
device. As the API evolved, we introduced a new, stricter check whose results
appear in a value called ctsProfileMatch, which allows developers
to more finely evaluate the devices on which their app is running.

In broad terms, basicIntegrity gives you a signal about the general
integrity of the device and its API. Rooted devices fail
basicIntegrity, as do emulators, virtual devices, and devices with
signs of tampering, such as API hooks.

On the other hand, ctsProfileMatch gives you a much stricter signal
about the compatibility of the device. Only unmodified devices that
have been certified by Google can pass ctsProfileMatch. Devices
that will fail ctsProfileMatch include the following:

  • Devices that fail basicIntegrity
  • Devices with an unlocked bootloader
  • Devices with a custom system image (custom ROM)
  • Devices for which the manufactured didn’t apply for, or pass, Google

  • Devices with a system image built directly from the Android Open Source Program source files
  • Devices with a system image distributed as part of a beta or developer
    preview program (including the Android Beta Program)

8. Not having a strategy for timing attestation checks

The SafetyNet Attestation API gives you a snapshot of the state of a device at
the moment when the attestation request was made. A successful attestation
doesn’t necessarily mean that the device would have passed attestation in the
past, or that it will in the future.

Because an attestation is just a spot check, you should plan a sensible strategy
for choosing when to make attestation requests. You may choose to require
successful attestations before users make in-app purchases, after a certain
number of days have passed since the last successful attestation, each time your
app is launched, after every reboot, or any other strategy that makes sense for
your app.

Keep in mind that an attestation request is computationally expensive, consumes
battery and bandwidth, and uses your quota. We recommend you plan a strategy to
use the least amount of attestations required to satisfy your use case.

9. Using the SafetyNet Attestation API results as the only signal
to attack abuse

It may be tempting to think that the SafetyNet Attestation API provides all the
necessary signals for protecting an app against abusers, and use it as the only
signal for building an anti-abuse system.

The SafetyNet Attestation API can only give signals about the state of
a device, not the intent of a user, which is what an anti-abuse system
should be designed to detect. Therefore, you might want to consider including
other signals, such as access logs and behavioral patterns, to more accurately
detect abusive users, and consider not blocking users solely on a failed
attestation. Furthermore, there are many other conditions that cause an
attestation to fail, such as network connection problems, quota issues, and
other transient problems.

In other words, not all users who fail attestation are necessarily abusers, and
not all abusers will necessarily fail attestation. By blocking users solely on
their attestation results, you might be missing abusive users that don’t fail
attestations. Furthermore, you might also be blocking legitimate, loyal
customers who fail attestations for reasons other than abuse.

10. Not monitoring and managing your usage quota

As mentioned before, the
SafetyNet Attestation API is rate limited, and there is a default quota of
10,000 requests per day for each API key. Although this quota might be enough
for most development, testing, and initial app launches, your app might reach
the default limit as it increases in popularity.

To prevent inadvertently reaching your quota and getting attestation errors, you
should build a system that monitors your usage of the API and warns you well
before you reach your quota so you can get it increased. You should also be
prepared to handle attestation failures because of an exceeded quota and avoid
blocking all your users in this situation.

If you are close to reaching your quota, or expect a short-term spike that may
lead you to exceed your quota, you can submit
this form to request short or long-term increases to the quota for your API
key. This process, as well as the additional quota, is free of charge.

Android Developers Blog

Sep 29

Keystore Key Attestation

Posted by Shawn Willden, Software Engineer

Android’s keystore has been available for many years, providing app developers
with a way to use cryptographic keys for authentication and encryption. Keystore
keeps the key material out of the app’s process space, so that the app cannot
inadvertently reveal it to the user where it could be phished, leak it through
some other channel, or have it compromised in the event of a compromise of the
app. Many devices also provide hardware-based security for keystore keys in
secure hardware, which keeps the key material out of the Android system
entirely, so that the key material cannot be leaked even by a Linux kernel
compromise. In the vast majority of Android devices, secure hardware is a
special mode of the main CPU, with hardware-enforced isolation from the Linux
kernel and Android userspace. Alternatively, some devices use a separate secure

Android provides APIs that allow the app to determine whether a given keystore
key is in secure hardware, but these APIs could be unreliable if the operating
system has been compromised. Key attestation provides a way for a device’s
secure hardware to verify that an asymmetric key is in secure hardware,
protected against compromise of the Android OS.

History of Keystore

Keystore was originally introduced in Android 4.0 and keys were encrypted with
the user’s passcode. In Android 4.1 the infrastructure to use device secure
hardware was added.

Up until Android 6.0, Keystore supported RSA and ECDSA. In Android 6.0, Keystore
was significantly enhanced, adding support for AES and HMAC. Also, other crucial
elements of cryptographic operations, such as RSA padding1 and AES block chaining2 modes were moved into secure hardware.

In Android 6.0, Keystore also gained the ability to restrict the ways in which a
particular key could be used. The most obviously useful restriction that can be
applied is user authentication binding. This allows a key’s usage to be
“bound” to the user’s passcode—their PIN, pattern, or password—or fingerprint.
For passcode authentication binding, the app developer can specify a timeout in
seconds. If more than the specified time has elapsed since the user last entered
their passcode, the secure hardware refuses any requests to use the key.
Fingerprint-bound keys require a new user authentication each time the key is

Other, more technical, restrictions can be applied to Android 6.0+ keys as well.
In particular, at point of key creation or import, it is necessary to specify
the cryptographic purposes (encrypt, decrypt, sign, or verify) for which the key
may be used, as well as padding and block modes, digests, source of entropy for
initialization vectors or nonces, and other details of the cryptographic
operation. Because the specified information is permanently and
cryptographically bound to the key material, Keystore won’t allow the key to be
used in any other way. Therefore, an attacker who gains control of the app or
the system can’t misuse the key. To help prevent attacks, developers should
specify the narrowest possible range of uses for a given key.

One of the most important changes to Android Keystore was introduced in Android
7.0. New devices that launch with Android 7.0+ with a secure lock screen must
have secure hardware and support hardware-based passcode authentication and
keystore keys. Prior to Android 7.0, secure hardware support was widespread, but
over the next few years it will become universal.

In Android 8.0, key attestation was made mandatory for all new devices that ship
with Google Play installed.

Why use key attestation?

Suppose you’re developing an app to provide a bank’s customers with access to
their bank balance, transaction history, and bill pay system. Security is
important; you don’t want anyone who picks up the user’s phone to have access to
their the bank account. One approach would be to use the user’s web site
password. But that’s often inconvenient for the user because web sites often
demand long, complex passwords, which are inconvenient on a small touchscreen.

With Android Keystore, you can generate an asymmetric authentication key, such
as a 256-bit ECDSA key, and have each user sign in with their complex web
password once, then register the public key in the bank’s customer account
database. Each time they open the app, you can execute a challenge-response
authentication protocol using that ECDSA key. Further, if you make the key
authentication-bound, the user can authenticate with their lock screen passcode
or fingerprint each time they open the app. That allows them to use the simpler
and more convenient authentication mechanism on their phone.

If an attacker compromises Android and attempts to extract the key, they
shouldn’t be able to because the key is in secure hardware.

As an app developer, key attestation allows you to verify on your server that
the ECDSA key your app requested actually lives in secure hardware. Note that
there’s little point in using the attestation in your app itself; if the Android
OS is uncompromised and trustworthy, then you can just use the KeyInfo
class introduced in 6.0 to discover whether the key is in secure hardware. If it
is compromised, then that API and any attempt you make to validate the
attestation on device are both unreliable.

Note that key attestation is distinct from SafetyNet
attestation. They’re the same concept, but attest to different things and
come from different places. Keystore key attestation affirms that a crypto key
lives in secure hardware and has specific characteristics. SafetyNet attestation
affirms that a device is real (not an emulator) and that it’s running known
software. SafetyNet uses Keystore key attestation under the covers, so if you
want to know about device integrity use that. If you want to confirm that your
key is in secure hardware, use key attestation.

For details and sample code, see the key
attestation training article on


  1. Keystore supports the recommended OAEP and PSS padding modes for RSA encryption and
    signing, respectively, as well as the older PKCS#1 v1.5 modes. ↩

  2. Keystore supports GCM, CBC and ECB block chaining modes. ↩

Android Developers Blog

Apr 28

SafetyNet attestation, a building block for anti-abuse

Posted by Arindam Basu, Borbala Benko, Alan Butler, Edward Cunningham, William Luh

Building innovative security features for Android app developers and their users
continues to be a priority. As part of this effort, we provide SafetyNet
, an API for developers to remotely evaluate whether they are
talking to a genuine Android device.

SafetyNet examines software and hardware information on the device to assess its
integrity. The result is a cryptographically signed statement, attesting basic
properties of the device — such as overall integrity and compatibility with
Android (CTS) — as
well as metadata about your app, such as its package name and signature. The
following JSON snippet shows an example of how the API reports this information:

  "nonce": "R2Rra24fVm5xa2Mg",
  "timestampMs": 9860437986543,
  "apkPackageName": "",
  "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,

The contents of an example attestation response, providing information about
the calling app and the integrity and compatibility of the device.

The SafetyNet attestation API can help your server distinguish traffic coming
from genuine, compatible Android devices from traffic coming from less-trusted
sources, including non-Android devices. This classification helps you better
understand the risks associated with each device so that you can fine-tune
preventive or mitigative actions in case of abuse or misbehavior.

We encourage developers to use SafetyNet attestations to augment their
anti-abuse strategy. Combine SafetyNet attestation with other signals, such as
your existing device-side signals and behavioral signals about what the user is
trying to do, in order to build robust, multi-tier protection systems.

For further information, check the recently
updated documentation and see the SafetyNet API
Samples on GitHub.

Android Developers Blog