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 most recent launch of the Play Integrity API, further builders are literally taking movement to protect their video video games and apps from most likely harmful and fraudulent interactions.

Together with useful indicators on the integrity of the app, the integrity of the machine, and licensing information, the Play Integrity API features a simple, however very useful operate often called “nonce” that, when appropriately used, can further strengthen the current protections the Play Integrity API affords, along with mitigate certain sorts of assaults, similar to person-in-the-middle (PITM) tampering assaults, and replay assaults.

On this weblog put up, we’ll take a deeper take a look at what the nonce is, the way in which it really works, and the way in which it could be used to further defend your app.

What’s a nonce?

In cryptography and security engineering, a nonce (amount as quickly as) is a amount that’s used solely as quickly as in a secure communication. There are quite a few functions for nonces, similar to in authentication, encryption and hashing.

Inside the Play Integrity API, the nonce is an opaque base-64 encoded binary blob that you just simply set sooner than invoking the API integrity check, and it’ll doubtless be returned as-is contained within the signed response of the API. Counting on the way in which you create and validate the nonce, it’s attainable to leverage it to further strengthen the current protections the Play Integrity API affords, along with mitigate certain sorts of assaults, similar to person-in-the-middle (PITM) tampering assaults, and replay assaults.

Apart from returning the nonce as-is throughout the signed response, the Play Integrity API doesn’t perform any processing of the actual nonce data, so as long as it’s a authentic base-64 price, you’ll be capable to set any arbitrary price. That talked about, as a technique to digitally sign the response, the nonce is shipped to Google’s servers, so this can be very essential to not set the nonce to any form of personally identifiable information (PII), such as a result of the particular person’s title, phone or e mail cope with.

Setting the nonce

After having prepare your app to utilize the Play Integrity API, you set the nonce with the setNonce() methodology, or its relevant variant, accessible throughout the Kotlin, Java, Unity, and Native variations of the API.

Kotlin:

val nonce: String = ...

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

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

Java:

String nonce = ...

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

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

Unity:

string nonce = ...

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

// Request the integrity token by providing 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 inside the kind of a JSON Web Token (JWT), whose payload is a plain-text JSON textual content material, throughout the following format:

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

The nonce shall be found contained within the requestDetails development, which is formatted throughout the following technique:

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

The price of the nonce topic ought to exactly match the one you beforehand handed to the API. Furthermore, given that nonce is contained within the cryptographically signed response of the Play Integrity API, it’s not doable to vary its price after the response is acquired. It’s by leveraging these properties that it’s attainable to utilize the nonce to further defend your app.

Defending high-value operations

Enable us to take note of the scenario by way of which a malicious particular person is interacting with a web-based recreation that research the participant score to the game server. On this case, the machine is simply not compromised, nevertheless the particular person can view and modify the neighborhood data stream between the game and the server with the help of a proxy server or a VPN, so the malicious particular person can report a greater score, whereas the true score is way lower.

Merely calling the Play Integrity API is simply not sufficient to protect the app on this case: the machine is simply not compromised, and the app is respectable, so all the checks achieved by the Play Integrity API will cross.

However, it’s attainable to leverage the nonce of the Play Integrity API to protect this specific high-value operation of reporting the game score, by encoding the price of the operation contained within the nonce. The implementation is as follows:

  1. The particular person initiates the high-value movement.
  2. Your app prepares a message it needs to protect, as an example, in JSON format.
  3. Your app calculates a cryptographic hash of the message it needs to protect. As an illustration, 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 topic to the cryptographic hash calculated throughout the earlier step.
  5. Your app sends every the message it needs to protect, and the signed outcomes 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 price of the nonce topic throughout the signed end result, and rejects any outcomes that don’t match.

The following 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.

As long as the distinctive message to protect is shipped along with the signed end result, and every the server and shopper use the exact same mechanism for calculating the nonce, this affords a strong guarantee that the message has not been tampered with.

Uncover that on this example, the security model works beneath the concept that the assault is happening throughout the neighborhood, not the machine or the app, so it’s considerably essential to moreover verify the machine and app integrity indicators that the Play Integrity API affords as properly.

Stopping replay assaults

Enable us to take note of one different scenario by way of which a malicious particular person is trying to work along with a server-client app protected by the Play Integrity API, nevertheless needs to take motion with a compromised machine, in a technique so the server doesn’t detect this.

To take motion, the attacker first makes use of the app with a good 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 identify, and as a substitute of performing the integrity checks, it merely returns the beforehand recorded signed response.

Given that signed response has not been altered in any technique, the digital signature will look okay, and the app server may be fooled into pondering it’s talking with a good machine. That is called a replay assault.

The first line of safety in opposition to such an assault is to substantiate the timestampMillis topic throughout the signed response. This topic accommodates the timestamp when the response was created, and shall be useful in detecting suspiciously outdated responses, even when the digital signature is verified as real.

That talked about, it’s additionally attainable to leverage the nonce throughout the Play Integrity API, to assign a singular price to each response, and verifying that the response matches the beforehand set distinctive price. The implementation is as follows:

  1. The server creates a globally distinctive price in a technique that malicious clients cannot predict. As an illustration, a cryptographically-secure random amount 128 bits or greater.
  2. Your app calls the Play Integrity API, and models the nonce topic to the distinctive price acquired by your app server.
  3. Your app sends the signed outcomes of the Play Integrity API to your server.
  4. Your server verifies that the nonce topic throughout the signed end result matches the distinctive price it beforehand generated, and rejects any outcomes that don’t match.

The following 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, each time the server asks the app to call the Play Integrity API, it does so with a particular globally distinctive price, so as long as this price can’t be predicted by the attacker, it’s not attainable to reuse a earlier response, as a result of the nonce gained’t match the anticipated price.

Combining every protections

Whereas the two mechanisms described above work in very other ways, if an app requires every protections on the an identical time, it’s attainable to combine them in a single Play Integrity API identify, as an example, by appending the outcomes of every protections into a much bigger base-64 nonce. An implementation that mixes every approaches is as follows:

  1. The particular person initiates the high-value movement.
  2. Your app asks the server for a singular price to ascertain the request
  3. Your app server generates a globally distinctive price in a technique that malicious clients cannot predict. As an illustration, chances are high you’ll use a cryptographically-secure random amount generator to create such a value. We propose creating values 128 bits or greater.
  4. Your app server sends the globally distinctive price to the app.
  5. Your app prepares a message it needs to protect, as an example, in JSON format.
  6. Your app calculates a cryptographic hash of the message it needs to protect. As an illustration, with the SHA-256, or the SHA-3-256 hashing algorithms.
  7. Your app creates a string by appending the distinctive price acquired out of your app server, and the hash of the message it needs to protect.
  8. Your app calls the Play Integrity API, and calls setNonce() to set the nonce topic to the string created throughout the earlier step.
  9. Your app sends every the message it needs to protect, and the signed outcomes of the Play Integrity API to your server.
  10. Your app server splits the price of the nonce topic, and verifies that the cryptographic hash of the message, along with the distinctive price it beforehand generated match to the anticipated values, and rejects any outcomes that don’t match.

The following sequence diagram illustrates these steps:

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

These are some examples of the way in which it is best to make the most of the nonce to further defend your app in opposition to malicious clients. In case your app handles delicate data, or is vulnerable in opposition to abuse, we hope you take note of taking movement to mitigate these threats with the help of the Play Integrity API.

To check further about using the Play Integrity API and to get started, go to the documentation at g.co/play/integrityapi.





Supply hyperlink

Leave a Reply

Your email address will not be published.