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.
Related
I want protect some files inside my project source code so if I sent source code to anyone he can only read the specific files and the protected ones can't read it without something like password or something else
I need to send all the project source code to someone and he can edit it and build the application normally but prevent him from access or read specific
I am not sure if there is something do that so if someone know is that possible please answer me
You can't. This comes up sometimes with keys and other sensitive files. What we do in cases like these is to have separate development/test/production keys or files and the developer has only access to a repository with the developer keys or files. Then on merge we merge in a way which means the final build will contain the production files the developer has no access to.
If you want to defend source code parts you can use obfuscation. This will still make the build work but it only makes the code harder to understand, not that it is unavailable. Note that if the developer wants to build the project locally it needs to access all the files the build will need, and that means read access.
I have an Android app public on the Github. Even if it is public I have some values like API keys that I don't want other people to see.
I've seen people storing them on gradle.properties but I have that file visible also.
I've see that the gitignore command will not commit that file at all in case I update it.
Question: Which is the best way to achieve this for Android projects and keep the project public?
There is a file called local.properties at the project root level which could be used to hold the api keys. It shouldn't be committed to source control.
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.
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/
We've been asked to create a thin web client on Android for a company with an existing web site, existing users.
They want to send an mms to their users, giving each user their own download URL. This URL will point to an Android apk file that has been created specifically for that user - it will include that user's login, and password, to the website.
i.e. the APK file would have embedded login details.
This would be done in J2ME by storing info in the JDK file.
I can see a simlar question on How to update resources file in apk - but not fully answered.
So:
is there a way to store an "asset" in the apk file that will be a text file, and easily editable by unzipping, editing, rezipping the apk file? (looks like answer is no)
do you know of any similar problems, or have worked on similar apps?
is there advice on how best to accomplish this application? Any sort of embedding of customer info on an automated level would be of interest...
would the best option be to set the app to build with an Ant script, and have the client actually customize the source code and build a new app per user? (this has the con that the client gets the source code, which we'd rather not have)
I have scanned apk tagged questions and can't seem to find a solution to this.
Many thanks,
Richard
I guess you could put it into the apk (or replace a dummy file there) if you use the assets folder for it.
You can obtain the data by filename instead resource-id quite easy:
getResources().getAssets().open(fileName)
Regards,
Oliver
If it absolutely has to be that way, consider distributing two APKs, one with the application and the other containing a file with the handset-specific information. Sign them both with the same key, arrange for them to share a UID and the application will be able to read the file as if it were its own.
The rest of this probably belongs in a comment and not this answer, but I see lots of problems with what you're being asked to do:
The standard behavior for just about every other application out there is to ask for a login and password once when needed and then remember it.
If the user changes his password on your customer's web site, he has to get a new APK for his device instead of just having to reauthenticate.
Any changes to the application will require generation and installation of a new APK for each user.
All it would take is some unwitting user sharing his unique APK with someone else and your whole security model goes right down the tubes.
Less relevant, but still important: If your customer is able to reconstitute a plaintext password from what they have stored, I question their security scheme.