What I'm trying to do:
Within Android, I've attempted to use SharedPreferences to store usernames within application memory. So users don't need to input their usernames every-time, but the app won't decrypt usernames. Without encryption it stores and returns usernames, but with AES-128 encryption usernames not decrypted/returned.
What's happening:
The program stores newly encrypted usernames in memory, but when the application attempts to decrypt them, nothing happens (username text-box is returned empty).
What the application was intended to do: (but isn't doing)
The user should input their username and password and if they click on the "Remember" check-box, upon press of the login button the application stores and then encrypts their username.
Upon future running of the app, if the check-box was previously checked their username would already appear typed in the username text-box. When the button function is complete, the application is then restarted by the "doSomethinghElse" subroutine, so to confirm to me that the app had worked and the unencrypted username has been returned. (But this isn't happening right now)
Actual Problem:
It's not decrypting and returning usernames. When encryption, try and catches are removed, the app returns the previous user's login details. But with the addition of encryption, the app doesn't return usernames.
To help people solve this problem, the below was based largely on the 2 links below:
http://www.androidsnippets.com/encryptdecrypt-strings
Code:
Crypto.java
public class Crypto {
public static String encrypt(String seed, String cleartext)
throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] result = encrypt(rawKey, cleartext.getBytes());
return toHex(result);
}
public static String decrypt(String seed, String encrypted)
throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] enc = toByte(encrypted);
byte[] result = decrypt(rawKey, enc);
return new String(result);
}
private static byte[] getRawKey(byte[] seed) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
kgen.init(128, sr); // 192 and 256 bits may not be available
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
return raw;
}
private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(clear);
return encrypted;
}
private static byte[] decrypt(byte[] raw, byte[] encrypted)
throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}
public static String toHex(String txt) {
return toHex(txt.getBytes());
}
public static String fromHex(String hex) {
return new String(toByte(hex));
}
public static byte[] toByte(String hexString) {
int len = hexString.length() / 2;
byte[] result = new byte[len];
for (int i = 0; i < len; i++)
result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2),
16).byteValue();
return result;
}
public static String toHex(byte[] buf) {
if (buf == null)
return "";
StringBuffer result = new StringBuffer(2 * buf.length);
for (int i = 0; i < buf.length; i++) {
appendHex(result, buf[i]);
}
return result.toString();
}
private final static String HEX = "0123456789ABCDEF";
private static void appendHex(StringBuffer sb, byte b) {
sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));
}
}