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
Related
So, i kind of created a monster. Built an android game for few years and used lots of hardcoded strings. Now i want to support different languages. My questions - is there an automatic way to create these resources?
for example tell Android studio for all the "hard coded" warnings apply extract string resource.
I aw aware of the inspect code that show you localization warnings, i am looking for a way to automate the fix
AFAIK, it's not possible to fix that automatically. You need to press Alt+Ctrl+Shift+i and type hardcoded strings. After completion of the finding process, manually create them in strings.xml.
I am attaching a link to site that will convert your string.xml to different language you want and then download translated string.xml in your stings folder, it will translate each string step by step, if this is what you want, hope it helps
https://asrt.gluege.boerde.de
Isn't strings.xml is supposed to be used as a text storage for easing the translation of text in the app to other languages?
For example - Facebook app id according to facebook manuals is advised to be stored in strings.xml.
It means that if I want to share this file with 3-th parties for translation - I will have to manually remove all ids by myself, or share those ids with 3-th parties.
Isn't strings.xml is supposed to be used as a text storage for easing the translation of text in the app to other languages?
No. It's string storage for any kind of strings. Majority of use is localization related but it is perfectly fine to have anything that is string there like API keys, tokens whatever.
Please be aware that you are not limited to just strings.xml file. You can have as many *.xml files holding string resources as you like (so it's quite common to split localization per class/functional module and keep it in separate xml file).
You can create more then one strings.xml you could name it appids.xml and store all your ids inside this file. It is common software design pardigm to seperate data from code, so you won't just use a String constant for your id.
For Android best practices, Google is the source to go, for example they propose the usage of an appids.xml file here: Getting started with Play Games
Facebook might be using this simpler form of storing your id to make the tutorial easier to follow.
Basically it may happen that the ids that you're going to use inside your app may occur in multiple java class files. So by mistake there may be a chance that you mistype the id or secret key which will result in failure of result that you are expecting. As a good practice you should store such things in strings.xml which will help you minimizing the possibility of error in your result. Also if you change your id or key because of any reason then you might have to change that in each file where you've mentioned it. Instead of that if you just change it in strings.xml then it will automatically reflect at every instance where you've used it.
Going further, Android is open source. Thus any app that you create can be reverse engineered and all the code can be read. This leads to leakage of your id's and may be some secret keys for any api that you've used inside your app.
I'm using in my Flashcards app strings.xml (value folder) as a database from where I extract the Questions & answers. Some colleagues told me that I'm miss-using string.xml!?
I really don't see any drawback using strings.xml as a database?
Do you agree with me regarding this point?
Do yo have better solution I mean better source code of a flashcards app to learn from it the best practices.
here is my code:
resId1=getApplicationContext().getResources().getIdentifier(
"textname" + 1, "string", getPackageName());
tex1=getResources().getString(resId1);
Many thank for your thoughts and assistance.
It is OK to use strings.xml as a read-only database, as long as you don't need to join data or do more advanced searches with it.
Using strings.xml is no different than using a text file as a "database" (I use that term lightly here).
You have to decide what's better for you here. Do you prefer to have a text file as a source of your data (which under certain circumstances can be completely viable) or do you need more control over your data (join, search, etc.).
If so, you can use the built in SqlLite to allow you to use an RDMBS but if not and you don't need to do anything other than having a read-only source of text, a text file approach is absolutely fine (even if it's in strings.xml).
I would suggest you to use Strings.xml as language file only, but if you think you don't have any confidential information's you are allowed to use Strings.xml as a database(but not recommended) however you can't store new values on runtime at Strings.xml.To handle some fewer data you can use SharedPreferences to store them and retrieve them, by (key, value) simple to use.
If u have large set of data then go for SQLite.
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.
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