So, I'm interested in obfuscating the SharedPreferences xml file of my app, much like Android LVL does to obfuscate it's license cahce data. Would this be conceivable? Plenty of google-digging has yielded little results that might address my question. And I'm certainly no cryptologist.
What about other forms of encryption? My end goal isn't to try making the xml bulletproof, I just want to block out the lower 90% of people who would refrain from messing around with it if it's not in plain text.
Don't believe this is possible, not without major modifications (possibly write your own Preferences implementation), and I couldn't even begin to think about how you would persuade Android to load from your Preferences implementation.
The default SharedPreferences implementation isn't replaceable as far as I can tell: if you need to encrypt something do what LVL does and either encrypt the value you write to the SharedPreferences XML, or create your own entirely encrypted file and manage it on disk yourself.
How about obfuscating the keys and values stored in the preference-XML?
I made a wrapper for the shared preferences which encrypt both keys and values: https://github.com/sveinungkb/encrypted-userprefs
Can you not use a scheme to change the data in some mannner so as to render it incomprehensible to most people? I can suggest one way. First, use fixed size string so that it does not change length with the data being saved. Next, you can apply some simple function to swizzle the bytes and offset each byte. So the end result will still be a string but it will make it hard for someone normal to figure out what it is, though a person bent on cracking it can succeed.
I've created a SharedPreferences implementation using AES encryiption.
The project is a maven module.
If you need one, take a look.
https://github.com/kovmarci86/android-secure-preferences
what you can do is.. wrap the sharedpreferences with your own method.. and avoid use your method name such as "Encrypt" "Decrypt" "String" etc.. because the proguard wont obfuscate the word..
here for example
https://github.com/afiqiqmal/ConcealSharedPreference-Android
Related
Right now they are just stored on a class called Globals as static fields.
I'm not the one who made the app, but I am considering putting them in localized strings.xml files, such as <string name="API_URL">http://someurl</string>. Is this good or bad practice?
UPDATE:
I chose the answer that I feel answers the question most comprehensibly.
But after some re-thinking, I have chosen a different solution alltogether.
Given that URLs are actually based on the country which the app should be distributed for, it doesn't make sense to switch them based on locale, as the URLs should stay the same regardless of the language on the phone.
Instead, I have implemented Gradle Flavors, which create different APKs based on different settings and such. It allows you to create variations of the same app with the small changes that you need. :) So now I have the URLs in a flavor-specific file.
Thank you to everyone who took their time to comment and help me.
I agree with puneet, it's neither good nor bad. It depends on what you are doing with the API Urls.
Are you going to append them later with user input? If so I would suggest you keep them as global variables that way you can modify the API URL programatically as needed.
If the API Url are complete and will not need to be appended then putting them in the strings.xml would be fine. Just remember that you would still have to create a local String variable in the java to hold the text from the API_URL in the string.xml, which seems inefficient if what you're aiming for is to write less code.
Neither good nor bad.If your concern is the security then none of them provide the security as decompilation is possible.
I've been trying to decompile and extract useful data from an APK for some time now. This data is stored in CSV files inside an "assets" folder. Unfortunately, the developers got smart, and have begun encrypting these CSVs starting in July. I've exhausted every way I know of to try and turn these files into readable versions of themselves without any success. But then, I realized, there are a few files in the assets folder that haven't changed since well before July—thus, I have both the decrypted and encrypted versions of these files. Using this knowledge, is it possible to predict the encryption pattern that all other files in the directory went through?
I'm fairly sure that it was encrypted bit-level, not byte-level since there are a lot of unknown characters (represented as special question marks) while trying to read these CSVs using Notepad/TextEdit/Atom in UTF-8 mode (or any other mode except UTF-16, really).
You're talking about a "known plain text" attack. No modern, widely used
method is vulnerable to this kind of attack, but many home grown encryption
methods are. Even with known text, you need to know or guess a lot about
the details of the encryption algorithm.
A better plan might be to hack the software that you know is doing the
decrypting, which must contain both the algorithm and the key.
You'd have better luck simply guessing based on the encrypted output. You'll need to familiarize yourself with characteristics of the output of algorithms and compare against what you see. This is probably a lot easier for hashes but you're talking about encryption. To answer your question though, it's unlikely that you're going to be able to use an unencrypted version of a file to break the encrypted one. You might try encrypting that file using different algorithms and comparing the results. That might give you the algo but could take longer.
Alternatively, here are some tools I found that might be able to automate the process for you...
https://code.google.com/archive/p/aligot/
https://bitbucket.org/daniel_plohmann/simplifire.idascope
https://www.aldeid.com/wiki/IDA-Pro/plugins/FindCrypt2
To crack it, you're also going to need to find the key that was used to encrypt it. Since it's a program that obvious must be decrypted to use, that key shouldn't be impossible to find. It's either in the apk or on a server somewhere in which case use wireshark but I'm guessing it's embedded.
They might be usig DexGuard or ProGuard. Here's a related post What methods are being used to protect this Android APK: Reflection? Encryption? How do I reverse engineer it and analyze it?
If it's ProGuard you might start with something like this: http://proguard.sourceforge.net/manual/retrace/examples.html
Here's some info on that: How to decode ProGuard's obfuscated code precisely?
Facebook in their user guide suggest to keep a key in values/strings.xml file. Have never seen such an approach before and it sounds odd for me. Is it something everybody use? I always thought is it better to keep such a data in config files.
It is perfectly alright to keep data like this in strings.xml. Make sure you keep it in the default /res/values/strings.xml and not in any other values folder which has qualifiers attached to it. It may not be available on all devices if you do that.
Keeping this kind of data in config files is also perfectly acceptable (and the one I personally use, more because I find it easier to edit a Java file with static variables than an XML file in Eclipse).
Keeping the data in strings.xml means having an additional step in accessing it, as you'll need to get it from the resources using an instance of Context. Putting it as a static field in a Java class will make it slightly easier to access.
Both methods work fine, and are used commonly. It is really upto your personal preferences to pick one.
I had stumbled upon this simple question of what is the best way for me to open a database or use a service which is secured, in the sense, will work only when correct password is provided.
I have looked at SharedPreferences as a way of retrieving information,but i need to create an app which will store the password in the first case, which by itself means i need to write it on code somewhere or the other
Account Manager is yet another way i've considered.
Store the actual password in an AES encrypted format, in a file, or in an sqlite db. But that means the key will have to be in the code.
I would've thought that this is a fairly common problem that people face and i'm wondering how people solved it!
In my opinion you can encrypt your data using AES encryption. But the main problem is the key is not safe. APK can be decompiled. So there is a method to hide the key. Implantation is bit difficult. Use native coding (NDK). You can write your key in a C file and after compilation you get a .SO file. This file can be included in your project. Make a call from java to a C function and return the key. But another problem is the strings written in C is visible when you open the .SO file. So assign generate ascii code of your key and make a string using the ascii code in C.
I know i can save strings in res/values/strings.xml but if someone disassembles the dex file or the apk file then he will be able to see HARDCODED strings or res/values/strings.xml strings.
Is there a way to store strings that wont be read if disassembled?
Briefly - no.
If you can decrypt/extract any string from your apk, potentially anyone with enough knowledge may look through your code and re-cosntruct the algorithm you use to extract those strings. And then extract them by herself.
Of course you may use some tricks to make it harder. What tricks can be used is actually up to you, Android doesn't provide any by default (AFAIK).
If you do not want the data to persist over application sessions, you can use SharedPreferences