The most talked about topic nowadays is security – be it human, home, country, website or smartphone. Talking in particular about the smartphone industry, it is inundated with the number of apps. The major concern of the app developers is the security of their mobile apps, particularly, to prevent their apps from reverse engineering.
What is Reverse Engineering of Mobile Applications?
With technological advancements, it is very easy to crack a mobile application, especially Android ones. The cracker can disable advertising, and can even detach it from various verification services.
Some might wish to crack the app (device, program, software) in order to find out the working and special features of your application; either to make a better app than yours or just completely reproduce it.
This particular practice is known as Reverse Engineering and has a wide variety of usage in manufacturing and even in military parlance.
The reverse engineering techniques involve the extraction of source code and various resources from the APK file. Decompiling an APK file is not a very hard task to do. It requires transforming dex files to jar files and then those jar files to java source code, thereby, fetching the app source code. There are numerous tools available for assistance such as Apktool, dex2jar, JD-GUI, and JAD.
It is very important to ensure the highest level of security to prevent mobile apps from reverse engineering.
Preventing Reverse Engineering of Mobile Apps
One can make it difficult to crack the mobile app by following the below guidelines:
1. ProGuard Assistance:
This is an open-source cross-platform tool written in Java, which helps in ensuring the security of mobile applications. It is a command-line tool that shrinks, optimizes, obfuscates and even pre-verifies the code. Let us explore how it works:
- Shrink Method: identify the unused classes, fields, methods attributes of the mobile app and remove them.
- Optimization: analyze and optimize the bytecode of various methods.
- Obfuscation: short meaningless names are given to the rest of classes, fields, and methods
The above steps make it difficult to reverse engineer an application by making codebase really smaller, more efficient and complicated.
- Pre verification: this process involves adding pre-verification information to the classes that are required by JME, Java 6 or higher.
For the prevention of Obfuscation, deobfuscators are available such as APK De-Guard. It uses machine learning, thereby making it one of the most accurate and efficient deobfuscators.
2. Save important code chunks on the server:
Another way of preventing apps from reverse engineering is to remove the code from the application and move it to any web service that is encrypted server-side language.
For instance, if a company is having a unique code or algorithm for their application, they would not allow their code to be stolen. They can prevent this by simply shifting their code or algorithm and let the data be processed on a remote server, thereafter, using the application to access that data.
3. Use C/C++ to write important codes:
A code written in Java is easy to decompile than the one written in C/C++. Therefore, developers sometimes use NDK to write crucial parts of their code natively into the .so files. Further, they add those files as a compiled library. Although, this code can be disassembled to assembly language code but the process of reverse engineering of a huge library can be cumbersome and time-consuming.
4. Be careful while applying SSL:
While interacting between server and device, developers use SSL for better security of their code.
There are several trivial methods contained in the class that implements an SSLSocketFactory interface. These trivial methods accept all types of certificates; thereby, making the application vulnerable to middle attacks (MitM). This might result in the loss of confidentiality of data transferred through the SSL/TSL protocol.
An attacker can easily breach the connection and get valuable data by simply providing a self-signed certificate.
5. Avoid storing values in raw format:
For storing values, it is not advised to use raw format. Suppose the value of user balance (in currency) needs to be stored, those values are to be saved in encoded form (for example, store them in the algorithm).
6. Securing User credentials:
It is advisable to secure the user credentials to avoid reverse engineering of the application.
- The frequency of seeking user credentials in the mobile application should be less. This will allow the apps to avoid phishing attacks, more likely to be unsuccessful. It is advisable to use an authorization token.
- The username and passwords should not be stored on the device. It is advisable to complete the initial authorization and use a short-lived authorization token.
To automate the authentication process of the app, the app owners require user credentials. In such cases use a credential object that contains user sign-in information.
7. Hide API keys:
Usually, third-party providers use an API key to grant access to the resources. Often, they use it to earn money from their data. It is recommended not to store the API keys in shared assets, resource folders, preferences or as a hardcode in Java. This is because they can be easily unzipped and the API can be decompiled to access the key. Use either NDK or Private/public key exchange to protect the API key.
8. Hashing algorithm:
Most of the hash functions MD2, MD5, SHA1 are vulnerable and prone to attacks. If they are used to store information like passwords, important information, confidentiality can be easily breached. Instead, use secure functions such as SHA-2.
A typical hash function should be resistant to collisions and not too fast. If a hash function is too fast, it complicates the attack by exhaustive search. For this specific purpose, specialized hash functions are developed such as PBKDF2, bcrypt, scrypt.
9. Use of reflection in an insecure manner:
It is possible to execute arbitrary malicious code. The argument taken by the method implementing reflection function is usually from an untrusted source. This facilitates the attackers to manage the control flow graph of the application; thereby, allowing them to bypass authentication mechanisms and get access to different restrictions.
In order to avoid this, create a whitelist of commands that you want in an application and ask the users to choose only from that list. Avoid using user-entered data directly as methods for implementing reflection.
Ensure to maintain the integrity and uniqueness of the configuration files while using them with reflection. In the absence of resources for security analysis, do not set the reflection parameters in configuration files.
10. Try not to use External storage
Files that are stored in external storage devices are readable by all applications. They can be easily changed whenever the user connects the USB storage device to the computer.
In case the application is deleted, the files are still there in the external storage. It might result in a loss of confidentiality of valuable data. It is, therefore, advised to store files in either internal memory or use the SQLite database.
11. Use Database Encryption
In order to enhance data security, it is advisable to secure database files. Those using SQLite can deploy an extension – SQLCipher, which is a set of open-source libraries. It is compact in size with low overhead and provides 256-AES encryption of SQLite database files in a transparent manner. It has become quite popular among the iOS developers to secure database files and it is also available for the Android developers as well.
It is not possible to protect the application from reverse engineering completely. But with the help of the above methods, you can try to secure Android apps to some extent.
If you have any other methods for securing mobile apps from reverse engineering, your thoughts are welcome in the comments below.