package de.pinyto.ctSESAM; import android.util.Log; import java.io.UnsupportedEncodingException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Arrays; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; /** * Encrypt with AES. Optionally creates a key. */ public class Crypter { private byte[] key; private byte[] iv; public Crypter(byte[] keyIv) { this.key = Arrays.copyOfRange(keyIv, 0, 32); this.iv = Arrays.copyOfRange(keyIv, 32, 48); Clearer.zero(keyIv); } public static byte[] createKey(byte[] password, byte[] salt) { return PBKDF2.hmac("SHA256", password, salt, 1024); } public static byte[] createIvKey(byte[] password, byte[] salt) { return PBKDF2.hmac("SHA384", password, salt, 32768); } public static byte[] createSalt() { SecureRandom sr = new SecureRandom(); byte[] salt = new byte[32]; sr.nextBytes(salt); return salt; } public static byte[] createIv() { SecureRandom sr = new SecureRandom(); byte[] salt = new byte[16]; sr.nextBytes(salt); return salt; } public byte[] encrypt(byte[] data) { return this.encrypt(data, "PKCS7Padding"); } public byte[] encrypt(byte[] data, String padding) { SecretKeySpec skeySpec = new SecretKeySpec(key, "AES"); try { Cipher cipher = Cipher.getInstance("AES/CBC/" + padding); cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(this.iv)); return cipher.doFinal(data); } catch (NoSuchAlgorithmException e) { Log.d("Encryption error", "AES/CBC is not implemented."); e.printStackTrace(); } catch (NoSuchPaddingException e) { Log.d("Encryption error", padding + " is not implemented."); e.printStackTrace(); } catch (InvalidAlgorithmParameterException e) { Log.d("Encryption error", "Invalid IV."); e.printStackTrace(); } catch (InvalidKeyException e) { Log.d("Encryption error", "Invalid key."); e.printStackTrace(); } catch (IllegalBlockSizeException e) { Log.d("Encryption error", "Illegal block size of the data."); e.printStackTrace(); } catch (BadPaddingException e) { Log.d("Encryption error", "Bad padding of the data."); e.printStackTrace(); } return new byte[] {}; } public byte[] decrypt(byte[] data) { try { return this.decrypt(data, "PKCS7Padding"); } catch (NoSuchPaddingException paddingError) { Log.d("Encryption error", "PKCS7Padding is not implemented."); paddingError.printStackTrace(); return new byte[] {}; } } public byte[] decrypt(byte[] encryptedData, String padding) throws NoSuchPaddingException { SecretKeySpec skeySpec = new SecretKeySpec(key, "AES"); try { Cipher cipher = Cipher.getInstance("AES/CBC/" + padding); cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(iv)); return cipher.doFinal(encryptedData); } catch (NoSuchAlgorithmException e) { Log.d("Encryption error", "AES/CBC is not implemented."); e.printStackTrace(); } catch (InvalidAlgorithmParameterException e) { Log.d("Encryption error", "Invalid IV."); e.printStackTrace(); } catch (InvalidKeyException e) { Log.d("Encryption error", "Invalid key."); e.printStackTrace(); } catch (IllegalBlockSizeException e) { Log.d("Encryption error", "Illegal block size of the data."); e.printStackTrace(); } catch (BadPaddingException e) { Log.d("Encryption error", "Bad padding of the data."); e.printStackTrace(); } return new byte[] {}; } }