Boost the security of your app with the nonce field of the Play Integrity API

 Boost the security of your app with the nonce field of the Play Integrity API

Posted by Oscar Rodriguez, Developer Relations Engineer

illustration with a mobile device displaying a security shield with a check mark, flow chart imagery, and Android logo

With the latest launch of the Play Integrity API, extra builders at the moment are taking motion to guard their video games and apps from doubtlessly dangerous and fraudulent interactions.

Along with helpful indicators on the integrity of the app, the integrity of the machine, and licensing data, the Play Integrity API incorporates a easy, but very helpful function known as “nonce” that, when accurately used, can additional strengthen the present protections the Play Integrity API gives, in addition to mitigate sure varieties of assaults, similar to person-in-the-middle (PITM) tampering assaults, and replay assaults.

On this weblog put up, we are going to take a deeper have a look at what the nonce is, the way it works, and the way it may be used to additional defend your app.

What’s a nonce?

In cryptography and security engineering, a nonce (quantity as soon as) is a quantity that’s used solely as soon as in a safe communication. There are various purposes for nonces, similar to in authentication, encryption and hashing.

In the Play Integrity API, the nonce is an opaque base-64 encoded binary blob that you just set earlier than invoking the API integrity verify, and will probably be returned as-is inside the signed response of the API. Relying on the way you create and validate the nonce, it’s doable to leverage it to additional strengthen the present protections the Play Integrity API gives, in addition to mitigate sure varieties of assaults, similar to person-in-the-middle (PITM) tampering assaults, and replay assaults.

Aside from returning the nonce as-is in the signed response, the Play Integrity API doesn’t carry out any processing of the precise nonce information, so so long as it’s a legitimate base-64 worth, you may set any arbitrary worth. That mentioned, as a way to digitally signal the response, the nonce is shipped to Google’s servers, so it is extremely vital to not set the nonce to any sort of personally identifiable data (PII), similar to the person’s title, telephone or e mail deal with.

Setting the nonce

After having arrange your app to make use of the Play Integrity API, you set the nonce with the setNonce() methodology, or its applicable variant, out there in the Kotlin, Java, Unity, and Native variations of the API.

Kotlin:

val nonce: String = ...

// Create an occasion of a supervisor.
val integrityManager =
    IntegrityManagerFactory.create(applicationContext)

// Request the integrity token by offering a nonce.
val integrityTokenResponse: Job<IntegrityTokenResponse> =
    integrityManager.requestIntegrityToken(
        IntegrityTokenRequest.builder()
             .setNonce(nonce) // Set the nonce
             .construct())

Java:

String nonce = ...

// Create an occasion of a supervisor.
IntegrityManager integrityManager =
    IntegrityManagerFactory.create(getApplicationContext());

// Request the integrity token by offering a nonce.
Job<IntegrityTokenResponse> integrityTokenResponse =
    integrityManager
        .requestIntegrityToken(
            IntegrityTokenRequest.builder()
            .setNonce(nonce) // Set the nonce
            .construct());

Unity:

string nonce = ...

// Create an occasion of a supervisor.
var integrityManager = new IntegrityManager();

// Request the integrity token by offering a nonce.
var tokenRequest = new IntegrityTokenRequest(nonce);
var requestIntegrityTokenOperation =
    integrityManager.RequestIntegrityToken(tokenRequest);

Native:

/// Create an IntegrityTokenRequest object.
const char* nonce = ...
IntegrityTokenRequest* request;
IntegrityTokenRequest_create(&request);
IntegrityTokenRequest_setNonce(request, nonce); // Set the nonce
IntegrityTokenResponse* response;
IntegrityErrorCode error_code =
        IntegrityManager_requestIntegrityToken(request, &response);

Verifying the nonce

The response of the Play Integrity API is returned in the kind of a JSON Net Token (JWT), whose payload is a plain-text JSON textual content, in the following format:

{
  requestDetails: { ... }
  appIntegrity: { ... }
  deviceIntegrity: { ... }
  accountDetails: { ... }
}

The nonce might be discovered inside the requestDetails construction, which is formatted in the following method:

requestDetails: {
  requestPackageName: "...",
  nonce: "...",
  timestampMillis: ...
}

The worth of the nonce field ought to precisely match the one you beforehand handed to the API. Moreover, since the nonce is inside the cryptographically signed response of the Play Integrity API, it isn’t possible to change its worth after the response is acquired. It’s by leveraging these properties that it’s doable to make use of the nonce to additional defend your app.

Defending high-value operations

Allow us to contemplate the situation during which a malicious person is interacting with a web based recreation that reviews the participant rating to the recreation server. On this case, the machine shouldn’t be compromised, however the person can view and modify the community information stream between the recreation and the server with the assist of a proxy server or a VPN, so the malicious person can report the next rating, whereas the actual rating is far decrease.

Merely calling the Play Integrity API shouldn’t be adequate to guard the app on this case: the machine shouldn’t be compromised, and the app is reliable, so all the checks performed by the Play Integrity API will move.

Nonetheless, it’s doable to leverage the nonce of the Play Integrity API to guard this specific high-value operation of reporting the recreation rating, by encoding the worth of the operation inside the nonce. The implementation is as follows:

  1. The person initiates the high-value motion.
  2. Your app prepares a message it desires to guard, for instance, in JSON format.
  3. Your app calculates a cryptographic hash of the message it desires to guard. For instance, with the SHA-256, or the SHA-3-256 hashing algorithms.
  4. Your app calls the Play Integrity API, and calls setNonce() to set the nonce field to the cryptographic hash calculated in the earlier step.
  5. Your app sends each the message it desires to guard, and the signed consequence of the Play Integrity API to your server.
  6. Your app server verifies that the cryptographic hash of the message that it acquired matches the worth of the nonce field in the signed consequence, and rejects any outcomes that do not match.

The next sequence diagram illustrates these steps:

Implementation diagram for encoding the value of the operation inside the nonce. Steps outlined in the body of the blog.

So long as the unique message to guard is shipped alongside with the signed consequence, and each the server and shopper use the very same mechanism for calculating the nonce, this gives a robust assure that the message has not been tampered with.

Discover that on this situation, the security mannequin works underneath the assumption that the assault is occurring in the community, not the machine or the app, so it’s notably vital to additionally confirm the machine and app integrity indicators that the Play Integrity API gives as effectively.

Stopping replay assaults

Allow us to contemplate one other situation during which a malicious person is making an attempt to work together with a server-client app protected by the Play Integrity API, however desires to take action with a compromised machine, in a manner so the server doesn’t detect this.

To take action, the attacker first makes use of the app with a reliable machine, and gathers the signed response of the Play Integrity API. The attacker then makes use of the app with the compromised machine, intercepts the Play Integrity API name, and as an alternative of performing the integrity checks, it merely returns the beforehand recorded signed response.

Since the signed response has not been altered in any manner, the digital signature will look okay, and the app server could also be fooled into pondering it’s speaking with a reliable machine. That is known as a replay assault.

The primary line of protection in opposition to such an assault is to confirm the timestampMillis field in the signed response. This field comprises the timestamp when the response was created, and might be helpful in detecting suspiciously outdated responses, even when the digital signature is verified as genuine.

That mentioned, additionally it is doable to leverage the nonce in the Play Integrity API, to assign a singular worth to every response, and verifying that the response matches the beforehand set distinctive worth. The implementation is as follows:

  1. The server creates a globally distinctive worth in a manner that malicious customers can not predict. For instance, a cryptographically-secure random quantity 128 bits or bigger.
  2. Your app calls the Play Integrity API, and units the nonce field to the distinctive worth acquired by your app server.
  3. Your app sends the signed consequence of the Play Integrity API to your server.
  4. Your server verifies that the nonce field in the signed consequence matches the distinctive worth it beforehand generated, and rejects any outcomes that do not match.

The next sequence diagram illustrates these steps:

Implementation diagram for assigning a unique value to each response, and verifying that the response matches the previously set unique value. Steps outlined in the body of the blog.

With this implementation, every time the server asks the app to name the Play Integrity API, it does so with a special globally distinctive worth, so so long as this worth can’t be predicted by the attacker, it isn’t doable to reuse a earlier response, as the nonce gained’t match the anticipated worth.

Combining each protections

Whereas the two mechanisms described above work in very alternative ways, if an app requires each protections at the similar time, it’s doable to mix them in a single Play Integrity API name, for instance, by appending the outcomes of each protections into a bigger base-64 nonce. An implementation that mixes each approaches is as follows:

  1. The person initiates the high-value motion.
  2. Your app asks the server for a singular worth to establish the request
  3. Your app server generates a globally distinctive worth in a manner that malicious customers can not predict. For instance, you might use a cryptographically-secure random quantity generator to create such a price. We advocate creating values 128 bits or bigger.
  4. Your app server sends the globally distinctive worth to the app.
  5. Your app prepares a message it desires to guard, for instance, in JSON format.
  6. Your app calculates a cryptographic hash of the message it desires to guard. For instance, with the SHA-256, or the SHA-3-256 hashing algorithms.
  7. Your app creates a string by appending the distinctive worth acquired from your app server, and the hash of the message it desires to guard.
  8. Your app calls the Play Integrity API, and calls setNonce() to set the nonce field to the string created in the earlier step.
  9. Your app sends each the message it desires to guard, and the signed consequence of the Play Integrity API to your server.
  10. Your app server splits the worth of the nonce field, and verifies that the cryptographic hash of the message, in addition to the distinctive worth it beforehand generated match to the anticipated values, and rejects any outcomes that do not match.

The next sequence diagram illustrates these steps:

implementation diagram for combining both protections. Steps outlined in the body of the blog.

These are some examples of methods you need to use the nonce to additional defend your app in opposition to malicious customers. If your app handles delicate information, or is susceptible in opposition to abuse, we hope you contemplate taking motion to mitigate these threats with the assist of the Play Integrity API.

To be taught extra about utilizing the Play Integrity API and to get began, go to the documentation at g.co/play/integrityapi.


Credit score: Source link

Read next