7

Problem

I have some keys which I want to keep it safe. At present, a native shared library generates them on demand. This shared library is used by my apk to get keys. The problem with the current implementation is that an attacker might extract apk, copy the shared lib and call the function that generates the keys and obtain the keys. Therefore I want to make sure that the shared lib generates valid keys only if it is called by my apk.

Approach to solve this problem

The approach to solve this problem involves apk tamper detection at NDK side. The basic idea is to get the signature of the calling APK at runtime from JNI. If the signature is valid, then the library generates valid keys, else it generates invalid keys.

Known limitations of this approach

  • It is understood that it is not 100% foolproof.
  • Since the keys are in client's device and the client owns the hardware, a dedicated attacker can access the generated key.

What have I done so far The implementation so far is based on the ideas mentioned in this stackoverflow post

  • Read the process memory which is stored in /proc/self/maps
  • Find the line containing the text '.dex'.
  • Get starting and ending addresses of the DEX file region

    FILE *fp;    
    fp = fopen("/proc/self/maps", "r");    
    if(fp!=NULL){
        char line [ 2048 ];
        while ( fgets ( line, sizeof line, fp ) != NULL ) /* read a line */
        {
            if (strstr(line, ".dex") != NULL) {
    
                //This is the line we want
                __android_log_write(ANDROID_LOG_INFO,"DexFile",line);
                char * startingAddress;
                char * endingAddress;
                startingAddress = strtok (line," ,.-");
                endingAddress = strtok (NULL," ,.-");
                if(startingAddress!=NULL){
                    __android_log_write(ANDROID_LOG_INFO,"DexStart",startingAddress);
                }
                if(endingAddress!=NULL){
                __android_log_write(ANDROID_LOG_INFO,"DexEnd",endingAddress);
                }
                //Now, we have the starting and ending address
            }
    
        }
        fclose ( fp);
    }
    

What I have not understood

  • Now that I have the starting address and ending address of dex file region, how do I get signature?
  • I am not sure why the signature needs to read in the first place. I thought that you need to read the checksum of apk in dex file region dex file format and if the checksum is not what you expect consider the apk as tampered.

  • How do I achieve what I am trying to do in a portable manner(since it involves native code)?

Note: If you can provide example implementations it would be great because I have been searching for this particular answer for long and I have only found abstract answers. Thanks in advance.

Community
  • 1
  • 1
Programmer
  • 1,290
  • 2
  • 12
  • 16
  • 1
    Another option might be to call the attestation api (http://developer.android.com/training/safetynet/index.html), and verify the results in native code. This will give you a signed "statement" from google that you can use as evidence that 1. the device is cts compliant (i.e. running an official, non-rooted firmware), and 2. the digest/signature of the app that the attestation request came from. It's still not bulletproof of course, especially since you would be verifying the signature on the client, but I think it would be at least as good as what you're trying to do. – JesusFreke Feb 19 '16 at 20:15
  • Did you find any solution on this? – Taras Oct 24 '16 at 22:20
  • @Taras You can see that: https://stackoverflow.com/a/50976883/3166697 – Dima Kozhevin Jun 22 '18 at 19:13

0 Answers0