The 01 September 2010 Android Developers' Blog discusses Securing Android LVL Applications. In order to make an app tamper resistant it describes the following technique :-
In order for an attacker to remove the LVL from your code, they have to
modify your code. Unless done precisely, this can be detected by your
code. There are a few approaches you can use here.
The most obvious mechanism is to use a lightweight hash function, such
as CRC32, and build a hash of your application’s code. You can then
compare this checksum with a known good value. You can find the path
of your application’s files by calling context.GetApplicationInfo() —
just be sure not to compute a checksum of the file that contains your
checksum! (Consider storing this information on a third-party server.)
What does this mean? Which file(s) is it that is supposed to be put into the hash function? And how would you compare the hash with the checksum (because surely if you then added a checksum comparison check to your sourcecode and rebuilt it, you'd get a different checksum?
Am I correct in thinking that this method is ONLY of any use if your app is able to get the checksum from a separate server?
Related
I was wondering what should be an ideal way for placing API keys, salts, or even private keys for encryption and ship them along with the APK. While doing research on this I saw a couple of methods widely used for placing some of these details:-
Place this info in gradle.properties - This is the simplest solution for placing these details but it is not secure at all. The information stored here can easily be extracted from the APK.
Store it in cpp - Create CPP files in the codebase where these details are placed and write JNIs to extract out these details when needed. This makes it harder for the attacker to extract out these details but it still is extractable
I read a couple of posts of which recommended using Keystore for securely storing this information but while seeing implementation at a couple of places I inferred that it usually stores values in runtime and I didn’t find any details on how to ship some salts or API keys along with the APK.
I wanted to know if there is any way for securely placing salts, API keys, etc along with the shipped APK. Or we can somehow use Keystore for this. Any help or suggestion will be really appreciated. Thank You!
Using this library You can easily secaure your api
https://github.com/MEiDIK/Cipher.so
Read Carefully there installation Process and still have any doubts or error i will help you
What I want to know is can a signed apk be extracted and edited? And can the attacker again compress the apk and attack a victim?
I know that we can use proguard to obscure the code but some people said that the apk still can be extracted and modified through reverse engineering.
My main concern is I want to encrypt my java files because I have some authentication data in my java files.
Can anyone give me a bulletproof method to protect java files from being inaccessible.
Edit -
Found few old thread in stack but they never explained about signed apk and protect them from getting exploited.
Yes. Cryptographic signing is not encryption. Signing proves that whoever signed it knew a secret key. Assuming the key is kept secure, you can be sure that two files signed by the same key are from the same person. With some forms of signing with public and private keys, it can be used to prove the identity of the signer. This does not provide any protection against reading that data, although it does provide protection against a counterfeit copy of the app being claimed as the real thing (assuming the user pays attention to the signature).
There is no way to do what you want to do. In the end, an app has to be run by a processor or interpreter. That means it needs to be translated into instructions that the processor understands. If you want something to be secure, do not put it on a client device. There is no way to protect it if you're sending it to a device that needs to decrypt it and use it.
Any APK can be decompressed and have its sources read. You cannot, however, edit it and sign it without the signing key.
There is no way to encrypt your source files and everything inside of them is readable by anyone. Authentication data shouldn't be stored in an application if it is expected to be secret.
signed apks can easily be reverse engineered. You should never place authentication data in the source code. There is no bullet proof solution for this. However you can make it difficult for the attacker by encoding and not placing your critical data in obvious places.
You should use another way to use your authentication data, I've read something about building a binary and storing inside the lib directory as a .so file, I'm not sure how exactly it's the proccess because I didn't tried, but you can research another methods, storing private data on Java source it's not secure.
If a hacker decompiled my APK would he be able to see my API keys from this file? I am not worried about my source code repository. I am just worried about a hacker being able to see this API key from my APK somehow. I'm trying to encrypt this file and decrypt it at runtime but having some issues
The way that the Google plugin is set up, it will be really hard for you to hide the content of the google-services.json file. The only viable way would be to re-implement yourself what the plugin already does for you, which I wouldn't recommend. When using the plugin the way Google intends you to, it will unfortunately be easy for anyone unzipping your APK to get hold of your Firebase/Google API Key.
However, you can prevent any abusive use of that API key by configuring who can use it. For an Android app, you can specify that your API Key can be used only by an Android application that has been signed by a given keystore and using a given package name.
To configure those restrictions, follow the documentation here: https://cloud.google.com/docs/authentication/api-keys#api_key_restrictions
On top of restricting the API Key, if you're using Firebase RTD/Firestore, you should also make sure that you configure security rules on the data store. Depending on your use-case, you can prevent anonymous user to read or write in sections of your database.
If you want more details, here is a good article I found on how to secure your API keys in an Android application:
https://proandroiddev.com/developing-secure-android-apps-8edad978d8ba
According to Firebase documentation here:
When you connect an app to your Firebase project, the Firebase console provides a Firebase configuration file (Android/iOS) or a configuration object (web) that you add directly into your local project.
For iOS, you add a GoogleService-Info.plist configuration file
For Android, you add a google-services.json configuration file
A Firebase config file or config object associates your app with your Firebase project and its resources (databases, storage buckets, etc.).
And then it identifies the content as public:
The content is considered public, including your platform-specific ID (entered in the Firebase console setup workflow) and values that are specific to your Firebase project, like your API Key, Realtime Database URL, and Storage bucket name.
Remember that, if you use Realtime Database, Cloud Firestore, or Cloud Storage, you still need to follow the security guidelines described by Firebase.
Also note that, although they are public for your application, these files should not be made available on public repositories of open source projects.
Everything in the app can be read in a very easy way, so as Google suggests you must avoid to put information in the apk, especially server key in case of firebase/google cloud messaging or services of this kind..
It's clearly not safe but you have no choice so it's important to limit your license keys.
Unzip your apk (either rename it to .zip and open, or from bash unzip [your apk path])
Now - le coup the grace: Find a file (in the root of the zip) named resources.arsc and open it with any editor that agrees to open it. Even TextEdit or Atom are enough. Search for AIza and here it is. With your user ID's.
... or the less Hacker-style method: Just drag and drop your APK to Android Studio. You can see everything inside: In resources.arsc you will find all the keys and values, all your strings, all your integers... all in easy beautiful GUI.
The bigger question: is there a way to tell ProGuard to obfuscate it efficiently.
Or is there a way to encrypt it with a secret key shared with a server.
MD5 fingerprint of any app can be easily acquired using keytool. Then what is the most unique identifier an app has?
I am trying to build a client server app and I want a secure the communications.
My problem revolves around these two assumptions -
1) Someone can reverse engineer my app and understand how I interact with server webservices
2) My app can be simply uninstalled and replaced with malicious app with similar package name.
The system can easily compromised using these two loopholes.
My solution to these problems was transmitting MD5 signature of my app to the server. The MD5 signature will be conveyed to server before hand. MD5 signature is unique for every app, But there is big problem in this approach. MD5 signature of any apk can be generated using keytool. Anyone may pull my apk and generate MD5 and use it in the webservices communication.
What is the unique identifier of an android app?
Package name and MD5 fingerprint can be easily compromised!
Basically you want to be sure that you are talking to your client app at server end.
Verify Back-End Calls from Android. This link could be helpful as it gives high confidence for such a case. (HTTPS is must here)
As an additional step for #Maddy 's answer, you might think about tamper resistance/integrity protection techniques, that will make your app inoperable in case somebody tried to modify it. DexProtector (http://dexprotector.com) could be the solution here. The slides under the link also should be helpful.
N.B.
I am Licel's CEO, thus I am affiliated with DexProtector.
First question
1) My app can be simply uninstalled and replaced with malicious app with similar package name.
best approach is probably the use of ANDROID_ID
Try this link http://blog.vogella.com/2011/04/11/android-unique-identifier/
Check this also http://android-developers.blogspot.in/2011/03/identifying-app-installations.html
Solution for the second issue
2) Someone can reverse engineer my app and understand how I interact with server webservices
Use DexGuard, which can make reverse engineering even harder, like by encrypting strings
https://www.saikoa.com/dexguard
Proguard
“The ProGuard tool shrinks, optimizes, and obfuscates your code by removing unused code and renaming classes, fields, and methods with semantically obscure names. The result is a smaller sized .apk file that is more difficult to reverse engineer.”
When you create android project.
1. proguard.cfg file is automatically generated in the root directory of the project.
2. The default configuration file only covers general cases, so customize as per your needs.
Enable it
“Set the proguard.config property in the /project.properties file. The path can be an absolute path or a path relative to the project’s root.”
Case1: Just add proguard.config=proguard.cfg if the proguard.cfg is in projects root path.
Case2: Configure from other location [proguard.config=/path/to/proguard.cfg]
Remove the “#” (or uncomment) the proguard configuring statement in project.properties. Which will be in commented initially.
Customize it. try this link http://1belong2jesus.wordpress.com/
I am developing an application that has SQLite database to store personal information that must be protected. What are some ways of protecting these personal data? An APK can easily be de-compiled completely, so how can we secure an APK? Additionally, how can a database of a mobile application be protected?
Basically, there are 5 methods to protect your APK being cracking/ reversing/ repackaging:
1. Isolate Java Program
The easiest way is to make users unable to access to the Java Class program. This is the most fundamental way, and it has a variety of specific ways to achieve this. For example, developers can place the key Java Class on the server, clients acquire services by access relevant interfaces of the server rather than access to the Class file directly. So there is no way for hackers to decompile Class files. Currently, there are more and more standards and protocols services provided through interfaces, such as HTTP, Web Service, RPC, etc. But there are lots of applications are not suitable for this protection. For example, Java programs in stand-alone programs are unable to isolate.
2. Encrypt Class Files
To prevent Class files from being decompiled directly, many developers will encrypt some key Class files, such as registration number, serial number management and other related classes. Before using these encrypted classes, the program needs to decrypt these classes first, then loading these classes into JVM. These classes can be decrypted by hardware, or software.
Developers often loading cryptographic classes through a customed ClassLoader class (Applet does not support customed ClassLoader because of security). Customed ClassLoader will find cryptographic classes first, then decrypt them. And finally loading the decrypted classes to JVM. Customed ClassLoader is a very important class in this protect method. Because it itself is not encrypted, it may be the first target of a hacker. If the relevant decryption key and algorithm have been overcome, then the encrypted classes can easily be decrypted.
3. Convert to Native Codes
Convert program to native codes is also an effective way to prevent decompilation. Because native codes are often difficult to be decompiled. Developers can convert the entire application to native codes, or they can also convert only key modules. If just convert key part of the modules, it will need JNI technology to call when Java programs are using these modules. It abandoned Java's cross-platform feature when using this mothod to protect Java programs. For different platforms, we need to maintain different versions of the native codes, which will increase software support and maintenance workload. But for some key modules, sometimes this solution is often necessary. In order to guarantee these native codes will not be modified or replaced, developers often need to digitally sign these codes. Before using these native codes, developers often need to authenticate these local codes to ensure that these codes have not changed by hackers. If the signature check is passed, then developers can call relevant JNI methods.
4. Code Obfuscation
Code obfuscation is to re-organize and process Class file, making the treated codes accomplish the same function (semantics) with the untreated codes. But the obfuscated codes are difficult to be decompiled, i.e., the decompiled codes are very difficult to understand, therefore decompile staffs are hard to understand the really semantics. Theoretically, if hackers have enough time, obfuscated codes may still be cracked. Even some people are developing de-obfuscate tool. But from the actual situation, since the diversified development of obfuscation, the mature of obfuscation theory, obfuscated Java codes can well prevent decompilation.
5. Online Encryption
APK Protect was an online encryption website for APK, but activity has apparently been discontinued since 2013 or so. It provided Java codes and C++ codes protection to achieve anti-debugging and decompile effects.
I originally suggested you use this last method for it could save you more time. Based on my experience, it was very simple to operate and it wouldn't take long time.
With Jellybean this has now become a possibility.
$ openssl enc -aes-128-cbc -K 000102030405060708090A0B0C0D0E0F
-iv 000102030405060708090A0B0C0D0E0F -in my-app.apk -out my-app-enc.apk
$ adb install --algo 'AES/CBC/PKCS5Padding' --key 000102030405060708090A0B0C0D0E0F
--iv 000102030405060708090A0B0C0D0E0F my-app-enc.apk
pkg: /data/local/tmp/my-app-enc.apk
Success
Please read the following blog post for further details
If this is secret information that must not fall into the hands of your users, you cannot secure it. It is fundamentally impossible to put information on a device (code or data), and have your application access it, but not allow someone with the device to have access to that information.
Encrypting the information is pointless from a security point of view, because your application has to contain whatever is needed to decrypt it in order to use it, and a sufficiently motivated attacker can always extract that and decrypt it on their own.
All you can do is make it more annoying and time consuming to get access to that information, which only helps if there's not really that much of a need to keep it secret. This is what using proguard to obfuscate your .apk file can do.
Have you considered sqlite encryption? See this thread - sqlite encryption for android
As for protecting your .apk, try obfuscating your code using proguard. See http://developer.android.com/guide/developing/tools/proguard.html
You can try 'Anti Decompiler(Android)Trial'
https://play.google.com/store/apps/details?id=com.tth.AntilDecompilerTrial
It makes something Proguard doesn't:
Hide all const values (string, character), you will never see clear text like "my key", "my val"... in your apk file
Obfuscate file name, which is referenced in AndroidManifest.xml
Add fake code to your source code. Event the powerful decompilers likes: dex2jar, jd-gui,... can't reverse exactly your apk file. Most of functions will show with comment 'Error'.
=====
After transforming, if you give someone your source project, it will be nearly impossible to read and understand.
This solution doesn't exclude Proguard, You can combine them together. (function, field Obfuscation of Proguard is better than Obfuscation features of this solution)
You may read my post at: http://www.androidpit.com/en/android/forum/thread/567093/An-Analysis-of-Android-APK-Protect-Shell-APKProtect. The APK added with protect shell of APK Protect is seems unable decompile. I mean, the encrypt method is very advanced. Even a master hacker need long time to crack it.
If it is the database that contains sensitive data you can encrypt the values of several columns or the full database like mentioned in the other answer and make sure that the password is not stored on the device but has to be entered by the user on accessing the data.
If there are pieces of code you need to protect there's really no good way of securing it. All you can for a limited amount of use-cases is to create a dependency to an online service and secure the server. But for a lot of applications this would not be an option.
First, make apk that can never be modified and used. I do it by temper detection from the server. I use root check emulator check. Then on the important activity, it checks root and emulator on every oncreate and on resume, deletes important data on onpause, Great. Now encrypt data and place license to server, use SSL server. It app can not be modified and run, everything is safe for ever. Well, how to avoid decompiler and online tamper detection. I do placing a huge code to generate some sample string from apk file, and compare it with an apk copy placed on the server. I have converted apk file to string. Just enjoy.