Detecting Device Tampering Using SafetyNet In Android
Posted By : Pushpandra Kumar | 30-Apr-2018
Today, I will discuss device tampering and why it is important. How we can check whether our device tampered or not.
So, let's first understand what actually is device tampering. Device Tampering is interfering with device's software or hardware. A tampered device is called in Tampered State. Tampered State can include a 'rooted device', 'device affected by malware' or 'device being monitored by some malicious piece of code'. A tampered state can have many definitions. A rooted device is a device in which a user gained root access via unlocking bootloader and modifying the system files. Tampering a device compromises user's security and privacy. Some app developers don't allow their applications to be run these tampered devices to avoid security risk. They use Google's Tampered detection tool called as SafetyNet to detect device tampering. It is the CTS compatibility status of a device that Google provides to requesting app as its opinion regarding CTS. CTS stands for Compatibility Test Suite which a device should pass before including Google Play Services. We cannot consider CTS compatible device vulnerability free device as it just checks if the device's expected normal state has tampered or not.
Steps to Use SateyNet Attestation/ Test :
1. Make a call to SafetyNetApi.attest(). This function connects to Google's servers by using GoogleApiClient.
2. Your request should include nonce to prevent replay attacks.
3. A JSON response is sent by Google with attestation result in JSON Web Signature(JWS) format (a signed JSON object) with "ctsProfileMatch" :true|flase.
4. Fields of JSON object need to be verified manually by the developer. By making another API call, the signature of response can also be verified by Google.
Code:
// We need different nonce for every request, Note : this is an example only, its not the secure way. Generate nonce securely // Generating nonce String nonceData = "Safety Net Sample: " + System.currentTimeMillis(); ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); byte[] bytes = new byte[24]; mRandom.nextBytes(bytes); try { byteStream.write(bytes); byteStream.write(nonceData.getBytes()); } catch (IOException e) { return null; } byte[] nonce = byteStream.toByteArray(); /* Call the SafetyNet API asynchronously. The result is returned through the success or failure listeners. First, get a SafetyNetClient for the foreground Activity. Next, make the call to the attestation API. The API key is specified in the gradle build configuration and read from the gradle.properties file. */ // Note : Implement your own Success and Failure listeners. This is just a sample code for reference SafetyNetClient client = SafetyNet.getClient(getActivity()); Tasktask = client.attest(nonce, BuildConfig.API_KEY); task.addOnSuccessListener(getActivity(), mSuccessListener) .addOnFailureListener(getActivity(), mFailureListener);
Hope you enjoyed my post, In Next post, I will discuss how SafetyNet Works behind the scenes.
Cookies are important to the proper functioning of a site. To improve your experience, we use cookies to remember log-in details and provide secure log-in, collect statistics to optimize site functionality, and deliver content tailored to your interests. Click Agree and Proceed to accept cookies and go directly to the site or click on View Cookie Settings to see detailed descriptions of the types of cookies and choose whether to accept certain cookies while on the site.
About Author
Pushpandra Kumar
Pushpender has experience in Core Java, C & C++. His hobbies are learning new technologies and listening music.