Is this implementation of AES for Android safe? Is it 128 bit encryption? How can I strengthen this implementation? Please help me, all suggestions are welcome :)
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.SecretKeySpec;
public class AESEncryption {
private static final String SecretKey = "9081726354fabced";
private static final String Salt = "03xy9z52twq8r4s1uv67";
private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";
private static final String KEY_ALGORITHM = "AES";
private static final String SECRET_KEY_ALGORITHM = "PBEWithSHA256And256BitAES-CBC-BC";
private static final String RANDOM_ALGORITHM = "SHA-512";
private static final int PBE_ITERATION_COUNT = 100;
private static final int PBE_KEY_LENGTH = 256;
private static final int IV_LENGTH = 16;
private Cipher cipher;
public AESEncryption() {
try {
cipher = Cipher.getInstance(CIPHER_ALGORITHM);
}
catch (NoSuchAlgorithmException e) {
cipher = null;
}
catch (NoSuchPaddingException e) {
cipher = null;
}
randomInt = new Random();
}
public SecretKey getSecretKey(String password) {
try {
PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray(), Salt.getBytes("UTF-8"), PBE_ITERATION_COUNT, PBE_KEY_LENGTH);
SecretKeyFactory factory = SecretKeyFactory.getInstance(SECRET_KEY_ALGORITHM);
SecretKey tmp = factory.generateSecret(pbeKeySpec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), KEY_ALGORITHM);
return secret;
}
catch (Exception e) {
return null;
}
}
public String encrypt(String text) {
Thread.sleep(randomInt.nextInt(100));
if (text == null || text.length() == 0) {
return null;
}
byte[] encrypted = null;
try {
byte[] iv = generateIV();
IvParameterSpec ivspec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(SecretKey), ivspec);
encrypted = cipher.doFinal(text.getBytes("UTF-8"));
}
catch (Exception e) {
return null;
}
return Base64.encodeToString(iv, Base64.DEFAULT)+Base64.encodeToString(encrypted, Base64.DEFAULT);
}
public String decrypt(String code) {
Thread.sleep(randomInt.nextInt(100));
if(code == null || code.length() == 0) {
return null;
}
byte[] decrypted = null;
try {
String iv64 = code.substring(0, IV_LENGTH*2);
String encrypted64 = code.substring(IV_LENGTH*2);
byte[] iv = Base64.decode(iv64, Base64.DEFAULT);
IvParameterSpec ivspec = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, getSecretKey(SecretKey), ivspec);
decrypted = cipher.doFinal(Base64.decode(encrypted64, Base64.DEFAULT));
}
catch (Exception e) {
return null;
}
return new String(decrypted, "UTF-8");
}
private byte[] generateIV() {
try {
SecureRandom random = SecureRandom.getInstance(RANDOM_ALGORITHM);
byte[] iv = new byte[IV_LENGTH];
random.nextBytes(iv);
return iv;
}
catch (Exception e) {
return null;
}
}
/*public static String bytesToHex(byte[] data) {
String HEXES = "0123456789ABCDEF";
if (data == null) {
return null;
}
final StringBuilder hex = new StringBuilder(2*data.length);
for (final byte b : data) {
hex.append(HEXES.charAt((b & 0xF0) >> 4)).append(HEXES.charAt((b & 0x0F)));
}
return hex.toString();
}*/
/*public static byte[] hexToBytes(String str) {
if (str == null) {
return null;
}
else if (str.length() < 2) {
return null;
}
else {
int len = str.length()/2;
byte[] buffer = new byte[len];
for (int i = 0; i < len; i++) {
buffer[i] = (byte) Integer.parseInt(str.substring(i*2,i*2+2),16);
}
return buffer;
}
}*/
}
Thanks a lot in advance!
Edit: The code throws an exception because Android can't find "PBEWithSHA256And256BitAES-CBC-BC". This is when I run the code on my phone, at least. What algorithm can I take now to replace this unknown one? The algorithm for SecretKeyFactory must be compatible to AES and the key size, right?