Android String Literals Obfuscation in Code.

We use ProGuard for code Obfuscation but it does not obfuscate hardcoded Strings present in the code. It changes the class names, method names and variable names but not the of variable values. Here the problem begins because anybody can reverse-engineer the apk and get the java files. Even if the code is obfuscated it just makes the code difficult to read for humans. By searching double quotes(“ ”) anybody can get all the hardcoded strings present in the code.

Many developers face this problem because they have to hardcode some strings in the development process. So there are many ways to solve this problem.

  1. Using cipher Algorithm:

This is one of the simplest approaches to handle this problem. We use cipher algorithm e.g. caesar cipher. We encrypt string literals and hardcode the encrypted value in the code. Before use at runtime, we decrypt the value using the same algorithm.

Drawback: The main drawback with this method is hackers can easily decrypt the encrypted string and get the original value. Another problem is the obfuscated code of the decryption algorithm can be understood with some effort.

2. Using Android default Encryption

Another approach to handle this problem is by using platform default algorithms e.g. SHA-1, MD-5 etc.

Drawback: The main drawback with this approach is we have to have at least a key for the encryption and decryption (whether this is a platform default encryption algorithm or your own algorithm). This key is hardcoded somewhere inside the code. A hacker can get it easily as Obfuscated code is just hard to understand.

3. Using a Third Party library

Next approach is by using external libraries like Dex-Gaurd, Stringer etc. At present these libraries are dependable and most of the big companies use them.

Drawback: Most of these libraries are commercial However, it’s an ongoing race between people trying to obfuscate the code and crackers. they can take your burden for now but sooner or later they will most likely also be reverse-engineered.

All of the above methods are traditional solutions but none of them hides the hardcoded string literals completely. found a solution to this problem.

We can use c/c++ code solve this problem. I keep defining my — string literals in c/c++ files and build using NDK which builds .so files. Below is an example.

I create a constant.c in jni folder parallel to java folder and add .mk file for NDK.

jstring BASE_URL_PROD = "https://abcd.com/";
JNIEXPORT jstring JNICALL
Java_com_dunzo_utils_JniHandler_getProdBaseUrl(JNIEnv *env, jobject instance) {
return (*env)->NewStringUTF(env, BASE_URL_PROD);
}

using “ndk-build” I get .so files which we keep in the lib folder.

To connect this to java code we have to load so file inside the library using

System.loadLibrary(“<lib-module name>”);

and In the end, I write native java function to connect library code to the java code

public native String getProdBaseUrl();

Now I can call this method using its object and I will get to string hard coded in c file.

Moral of The Story…

So, if you want to keep naked strings in frontend code then there are methods to get them. Methods can make it a tough but its literal cat and mouse game. the better method you use more time for you to crack it.