2

I am trying to store api keys using NDK but i tried somany methods always somany error I will share my code please any body help me..

I will share my steps i followed ..

1 Create a folder “jni” under src/main

2 Create and add “Android.mk” file under “jni” folder with following content:

     LOCAL_PATH := $(call my-dir)

    include $(CLEAR_VARS)

    LOCAL_MODULE    := keys
    LOCAL_SRC_FILES := keys.c

    include $(BUILD_SHARED_LIBRARY)
  1. Create and add “Application.mk” file under “jni” folder with the following content:

    APP_ABI := all
    
  2. Create the C/C++ file “keys.c” and add it under “jni” folder. Add the following content to it:

     # include < jni.h >
    
    JNIEXPORT jstring JNICALL
    Java_com_mytest_aes_MainActivity_getNativeKey1(JNIEnv *env, jobject instance) {
    
        return (*env)->NewStringUTF(env, "haii");
    }
    
  3. In the Activity where you want to access the keys (in our case MainActivity), create a static block and load the library “keys” like:

     static
     {
         System.loadLibrary("keys");
     }
    
  4. Declare two member function of type native to access the keys from the C/C++ file. Since we have stored 2 keys, we will declare 2 functions:

         public native String getNativeKey1();
    
  5. For demo, access the keys in the code like:

        String key1 = new String(Base64.decode(getNativeKey1(),Base64.DEFAULT));
    
    
        ((TextView)findViewById(R.id.key)).setText("Key1-->"+key1);
    
  6. Now, our C/C++ native files and Java code are ready. But to compile or make the native build using NDK, we need to add entry into the gradle file:

    android {
        .....
        buildTypes {
            .....
        }
        externalNativeBuild {
            ndkBuild {
                path 'src/main/jni/Android.mk'
            }
        }
    }
    

    We need to provide the path for our “Android.mk” file.

  7. Now, sync and build the project. Make sure, you have pointed the NDK path correctly in your module settings.

  • _"always somany error"_ You forgot to include the exact error messages in your question. – Michael Apr 02 '18 at 12:56
  • 1
    What makes you think You can secure API keys in NDK? I followed a Tutorial, generated the apk, and then got the .so files from apk (It’s newbie stuff). I created another project with the same package name and placed the .so files in the jni folder, and call the same method (there are multiple ways to list the methods of .so file). All set!!. Run the app and all my secret things were out ;) – Waqar Khan Oct 15 '18 at 09:44
  • @WaqarKhan is there any better way? – usernotnull Dec 28 '18 at 12:59
  • 4
    @RJFares Yes, there is a better (but not 100% secure) way. You have to get you keystore signature inside the NDK code and convert it to a string using toCharsString() method. Now you'll get a String of about 200+ length. Now substring that string and use that substring as a Key to encrypt the API key. Now Place your encrypted API key in NDK method as above along with the Encryption Key generated from keystore's signature's substring. Now get both Encryption Key and Encrypted API Key in Java and Decrypt the API key. – Waqar Khan Jan 10 '19 at 12:22
  • 1
    If Someone tried to copy your .so libs to another project. His keystore will be different of course and he'll get different Encryption key and will not be able to decrypt your API key. – Waqar Khan Jan 10 '19 at 12:22
  • @WaqarKhan that's the best answer i found online thanks :) – usernotnull Jan 10 '19 at 12:53
  • @Khan is there a tutorial or something that shows what you described ? of how to "substring that string and use that substring as a Key to encypt the API key " ? – isJulian00 May 22 '19 at 20:18
  • @RJFares were you able to implement this solution or have example code ? – isJulian00 May 22 '19 at 20:25
  • 1
    @Julian I didn't have to use it yet, but I asked for general info. I think it would make a great boost on his reputation for someone to write down completely the steps, but maybe also make it easier for hackers to reverse it if it's not 100% secure – usernotnull May 24 '19 at 03:23
  • Agreed with @RJFares, @Julian. Following is the code to substring from 0 to 20, you can also add some hardcoded text anywhere between or XOR it to make it more secure. `ts` is the long signature key. `jstring key = reinterpret_cast(ts); const char *s = env->GetStringUTFChars(key, 0); char entityID[20]; strlcpy(entityID, s, 20); key = env->NewStringUTF(entityID);` – Waqar Khan Jul 11 '19 at 12:14

1 Answers1

1

There are different ways in which API keys can be kept secure.

Best practice for storing and protecting private API keys in applications

Securing API Keys using Android NDK

https://medium.com/@abhi007tyagi/storing-api-keys-using-android-ndk-6abb0adcadad

Don't forget to define the NDK path correctly in your module settings. (File -> Project Structure -> SDK Location Tab -> Android NDK Location)

Note that using NDK, it's not full proof and you can still extract the keys. However, this will add an extra layer of obfuscation for your keys.

The suggested solution:- Can be used as a combination of multiple methods like Obfuscation, Encryption, Using NDK, Storing keys in Server, https integration, etc. based on the sensitivity of data in your application.

Amal Dev S I
  • 938
  • 13
  • 18