简体   繁体   中英

Android equivalent of ios devicecheck

Is there an android equivalent of ios device check https://developer.apple.com/documentation/devicecheck or any way to verify that this is your undoctored apk making the api call?

Edit: Just going to update this post with some third party solutions I have come across as well, these work for both ios and android.

freeRASP

AppiCrypt

First part of the question

Is there an android equivalent of ios device check https://developer.apple.com/documentation/devicecheck

As already point out the android equivalent is SafetyNet, but despite being a very good improvement for the Android security ecosystem was not designed to be used as a stand-alone defence, as per Google own statement :

The goal of this API is to provide you with confidence about the integrity of a device running your app. You can then obtain additional signals using the standard Android APIs. You should use the SafetyNet Attestation API as an additional in-depth defense signal as part of an anti-abuse system, not as the sole anti-abuse signal for your app.

Also when a developer is implementing the SafetyNet solution it needs to bear in mind:

  • It is part of Google Mobile Services (GMS) so only runs on devices that have this. In some markets, such as the far east, there are a significant number of devices that do not have this available.

  • There are a limited number of attestation calls that can be made with a standard free API key, so to use at scale a (presumably) paid level would be required.

  • It is primarily designed to check if the OS image that a particular Android device is running is considered to be secure and compatible or not. As such it can be considered to be quite advanced root check that is able to check for file system changes indicative of rooted devices.

  • Since the SafetyNet is doing a full analysis of the hashes of the OS image it can actually be quite slow (sometimes a few seconds). This means that it cannot be doing continuously and some care is needed in its use to hide this latency from the user, but without creating an opening for an attacker to exploit.

  • SafetyNet does not specifically analyse the memory map of running apps to detect instrumentation frameworks (it relies on the fact that they can only run on rooted devices), like XPosed and Frida.

  • SafetyNet does provide an attestation of the running app via the apkDigestSha256 feature. However, this can only be relied upon if full integrity is reported. This means that the integrity of the app is unknown if it is running on any kind of unusual or rooted devices. Some users root their devices only for customizations purposes and if the mobile app has a significant percentage of them then SafetyNet will exclude them from being able to use the app. In this scenarios we want to know specifically about the integrity of the running app rather then the system as a whole. SafetyNet is not able to do that, but a mobile app attestation service can.

  • In order to perform the attestation check in a way that cannot be spoofed then app cannot do its own check (as obviously this code could be tampered with itself). Thus there is a need to implement a server side to use the feature reliably.

Second part of the question

or any way to verify that this is your undoctored apk making the api call?

The way here is to use SafetyNet alongside a Mobile App Attestation service. OAUTH2 should also be used if user authentication and authentication is necessary in your mobile app. Last but not least important is the use of certificate pinning to secure the communication channel between the API server and the Mobile App, as covered in this series of articles about Mobile API Techniques.

Definition of a Mobile App Attestation service

The role of a Mobile App Attestation service is to guarantee at run-time that your App was not tampered or is not running in a rooted device by using an SDK integrated in your App and a service running in the cloud.

On successful attestation of the App Integrity a JWT token is issued and signed with a secret that only the API server of your App and the Mobile App Attestation service in the cloud are aware.

In the case of failure on the App Attestation the JWT is signed with a secret that the API server does not know.

Now the App must sent with every API call the JWT token in the headers of the request. This will allow the API server to only serve requests when it can verify the signature in the JWT token and refuse them when it fails the verification.

Once the secret used by the Mobile App Attestation service is not known by the App, is not possible to reverse engineer it at run-time even when the App is tampered, running in a rooted device or communicating over a connection that is being the target of a Man in the Middle Attack. This is where this type of service shines in relation to the SafetyNet solution.

As a side note if your App talks directly with third parts services, then I suggest that you delegate that responsibility to the API server, that will prevent unauthorized use of your third part services in your behalf, once it only serves now authentic requests from the Mobile App's that passed the Integrity challenges.

The Mobile App Attestation service already exists as a SAAS solution at Approov (I work here) that provides SDKs for several platforms, including iOS. The integration will also need a small check in the API server code to verify the JWT token issued by the cloud service. This check is necessary for the API server to be able to decide what requests to serve and what ones to deny.

They have SafetyNet - somewhat more comprehensive: https://developer.android.com/training/safetynet/index.html

The two APIs you'll want to look at are Attestation and Verify Apps:

The Attestation API checks a device's integrity while the Verify Apps API checks whether there are known potentially harmful apps installed. For added security protection, you should verify the device's integrity using the Attestation API before using the Verify Apps API.

As for the second part of your question, whatever you bake into your APP you should consider already compromised because an attacker can decompile your APP. You are better off focussing on proper server side security and limit what your API actually exposes, proper encryption, tokenization (if dealing with payment info), and adequate logging to track nefarious calls to your API. There's a reason you hire specialized developers once you're big enough to attract the attention of hackers.

Yes, there is. To ensure your backend receives only legit API calls from a genuine application you have to focus on the following aspects:

  • Supported platforms - there are crossplatform API protection solutions like Talsec AppiCrypt or Android flavor specific like Huawei-only Safety Detect Kit or Google Mobile Services SafetyNet .
  • Android vendor specifics :
Android Flavor Available Solution
vanilla Android - self-care kiosks, EMV POS terminals, Lineage OS, Healthcare tablets AppiCrypt
Google Mobile Services - Samsung, Xiaomi, OnePlus, etc. Google SafetyNet, AppiCrypt
Huawei Mobile Services - Huawei, Honor Attestation API, AppiCrypt
  • Performance impact - ie. SafetyNet brings some latency caused by remote data processing and evaluation. AppiCrypt delivers a stable <10 ms response time.

  • 3rd party elements - using 3rd party servers (ie, Google SafetyNet, which is not under your control) may be an issue for your business if you need a guaranteed operation

  • Threat details level - do you need fine-grained threat analysis and be able to react accordingly? The SafetyNet result is binary: safe or dangerous device. Should you need to be more specific, AppiCrypt has a detailed heuristic weight system for threat evaluation.

Android has a native solution available for this - KeyPairGenerator

Sample to generate a new key pair if one does not already exist -

KeyPairGenerator kpg = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore"); 
kpg.initialize(new KeyGenParameterSpec.Builder( 
        alias, // Key identifier 
        KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY) 
    .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512) 
    .setAttestationChallenge(attestationChallenge) 
    .build()); 
KeyPair kp = kpg.generateKeyPair();

Notes:

  1. You must specify a non-null attestationChallenge to KeyPairGenerator.initialize method to create a valid attestation object, otherwise you will get a fake certificate chain.
  2. attestationChallenge can be obtained by calling your server's respective endpoint to generate a one time challenge.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM