I need to store a username and a password that are common through the whole app, since they are for connecting to a hotspot in my Android app, but I'm not really sure how to do this, or how to encrypt them.
Any suggestion?
I need to store a username and a password that are common through the whole app, since they are for connecting to a hotspot in my Android app, but I'm not really sure how to do this, or how to encrypt them.
Any suggestion?
Answer mentioned by Greg Ennis, provides you the code to encrypt the string. We have various encryption algorithms for this.
Now the challenge is - what if the application source code is reverse engineered and the data is stolen ?
To protect the code against this, try the below solutions.
Solution 1 - Proguard
ProGuard obfuscates the Java jar file before it’s converted to a classes.dex file.
Refer to the SO Link Enabling ProGuard in Eclipse for Android to understand how to configure proguard in your application.
Read this link to understand the different options we can configure in a proguard properties file. http://proguard.sourceforge.net/manual/examples.html#androidapplication
One other easy option would be to use the proguard GUI
To launch the GUI, download it from SourceForge at http://proguard.sourceforge.net. Unzip it and execute the following command in the lib folder, assuming you’ve copied your target proguard.cfg file into the proguard\lib folder. You should see that many of the optimization options
Solution 2 - DashO interface (Commercial Tool)
This includes Control Flow,Renaming, and String Encryption obfuscation options.
Using a DashO interface is very simple with the GUI.
Hope this information helps.
If you store credentials as plain text in your app, someone can easily decompile and see the passwords. If you attempt to encrypt the information, where do you put the encryption key? You have the same problem.
There is a blog post from Google discussing a strategy for handling credentials. However, it only discusses storing credentials received at runtime, such as auth tokens or passwords the user typed. It completely avoids the question posed and the more common scenario of storing known credentials, because there is no answer for it
So, I usually put a small effort in to obfuscate the information so that only someone really dedicated to know the information would see it. This just a small barrier to prevent casual inspection of your information (for example, API keys). To do this, I use this helper class:
public class Obfuscator {
private final String _P = "(PUT A RANDOM 16-CHAR STRING HERE)";
public String obfuscate(String value) throws GeneralSecurityException {
byte[] raw = _P.getBytes(Charset.forName("US-ASCII"));
if (raw.length != 16) {
throw new IllegalArgumentException("Invalid key size.");
}
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(new byte[16]));
byte[] bytes = cipher.doFinal(value.getBytes(Charset.forName("US-ASCII")));
return Base64.encodeToString(bytes, Base64.NO_WRAP);
}
public String deobfuscate(String encrypted) throws GeneralSecurityException {
byte[] bytes = Base64.decode(encrypted, 0);
byte[] raw = _P.getBytes(Charset.forName("US-ASCII"));
if (raw.length != 16) {
throw new IllegalArgumentException("Invalid key size.");
}
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec,
new IvParameterSpec(new byte[16]));
byte[] original = cipher.doFinal(bytes);
return new String(original, Charset.forName("US-ASCII"));
}
}