关于java:使用AES进行Android加密/解密

Android encryption / decryption using AES

有没有一个很好的例子,如何加密和解密图像和其他文件与AES在Android上?


警告:此答案包含不安全的代码(使用sha1prng进行密钥派生,并在ecb模式下使用aes)相反,在CBC或GCM模式(GCM提供隐私和完整性)中,使用PBKDF2WITHHMACSHA1进行密钥派生和AES。

您可以使用如下函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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;
}

像这样调用它们:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ByteArrayOutputStream baos = new ByteArrayOutputStream();  
bm.compress(Bitmap.CompressFormat.PNG, 100, baos); // bm is the bitmap object  
byte[] b = baos.toByteArray();  

byte[] keyStart ="this is a key".getBytes();
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(keyStart);
kgen.init(128, sr); // 192 and 256 bits may not be available
SecretKey skey = kgen.generateKey();
byte[] key = skey.getEncoded();    

// encrypt
byte[] encryptedData = encrypt(key,b);
// decrypt
byte[] decryptedData = decrypt(key,encryptedData);

这应该有效,我现在在一个项目中使用类似的代码。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import java.security.AlgorithmParameters;
import java.security.SecureRandom;
import java.security.spec.KeySpec;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

class SecurityUtils {

  private static final byte[] salt={ (byte) 0xA4, (byte) 0x0B, (byte) 0xC8,
      (byte) 0x34, (byte) 0xD6, (byte) 0x95, (byte) 0xF3, (byte) 0x13 };

  private static int BLOCKS = 128;

  public static byte[] encryptAES(String seed, String cleartext)
      throws Exception {
    byte[] rawKey = getRawKey(seed.getBytes("UTF8"));
    SecretKeySpec skeySpec = new SecretKeySpec(rawKey,"AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
    return cipher.doFinal(cleartext.getBytes("UTF8"));
  }

  public static byte[] decryptAES(String seed, byte[] data) throws Exception {
    byte[] rawKey = getRawKey(seed.getBytes("UTF8"));
    SecretKeySpec skeySpec = new SecretKeySpec(rawKey,"AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.DECRYPT_MODE, skeySpec);
    return cipher.doFinal(data);
  }

  private static byte[] getRawKey(byte[] seed) throws Exception {
    KeyGenerator kgen = KeyGenerator.getInstance("AES");
    SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
    sr.setSeed(seed);
    kgen.init(BLOCKS, sr); // 192 and 256 bits may not be available
    SecretKey skey = kgen.generateKey();
    byte[] raw = skey.getEncoded();
    return raw;
  }

  private static byte[] pad(byte[] seed) {
    byte[] nseed = new byte[BLOCKS / 8];
    for (int i = 0; i < BLOCKS / 8; i++)
      nseed[i] = 0;
    for (int i = 0; i < seed.length; i++)
      nseed[i] = seed[i];

    return nseed;
  }

  public static byte[] encryptPBE(String password, String cleartext)
      throws Exception {
    SecretKeyFactory factory = SecretKeyFactory
        .getInstance("PBKDF2WithHmacSHA1");
    KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 1024, 256);
    SecretKey tmp = factory.generateSecret(spec);
    SecretKey secret = new SecretKeySpec(tmp.getEncoded(),"AES");

    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, secret);
    AlgorithmParameters params = cipher.getParameters();
    byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
    return cipher.doFinal(cleartext.getBytes("UTF-8"));
  }

  public static String decryptPBE(SecretKey secret, String ciphertext,
      byte[] iv) throws Exception {
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));
    return new String(cipher.doFinal(ciphertext.getBytes()),"UTF-8");
  }

}


如nacho.l所述,使用带有hmacsha1派生的pbkdf2,因为它更安全。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import android.util.Base64;

import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

public class AESEncyption {

    private static final int pswdIterations = 10;
    private static final int keySize = 128;
    private static final String cypherInstance ="AES/CBC/PKCS5Padding";
    private static final String secretKeyInstance ="PBKDF2WithHmacSHA1";
    private static final String plainText ="sampleText";
    private static final String AESSalt ="exampleSalt";
    private static final String initializationVector ="8119745113154120";

    public static String encrypt(String textToEncrypt) throws Exception {

        SecretKeySpec skeySpec = new SecretKeySpec(getRaw(plainText, AESSalt),"AES");
        Cipher cipher = Cipher.getInstance(cypherInstance);
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(initializationVector.getBytes()));
        byte[] encrypted = cipher.doFinal(textToEncrypt.getBytes());
        return Base64.encodeToString(encrypted, Base64.DEFAULT);
    }

    public static String decrypt(String textToDecrypt) throws Exception {

        byte[] encryted_bytes = Base64.decode(textToDecrypt, Base64.DEFAULT);
        SecretKeySpec skeySpec = new SecretKeySpec(getRaw(plainText, AESSalt),"AES");
        Cipher cipher = Cipher.getInstance(cypherInstance);
        cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(initializationVector.getBytes()));
        byte[] decrypted = cipher.doFinal(encryted_bytes);
        return new String(decrypted,"UTF-8");
    }

    private static byte[] getRaw(String plainText, String salt) {
        try {
            SecretKeyFactory factory = SecretKeyFactory.getInstance(secretKeyInstance);
            KeySpec spec = new PBEKeySpec(plainText.toCharArray(), salt.getBytes(), pswdIterations, keySize);
            return factory.generateSecret(spec).getEncoded();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return new byte[0];
    }

}


旧问题,但我升级了支持Android的回答,之前和之后4.2,并考虑到所有最近的变化,根据Android开发者博客。

另外,我在Github回购协议上留下了一个工作示例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import java.nio.charset.Charset;
import java.security.AlgorithmParameters;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;


/*
* This software is provided 'as-is', without any express or implied
* warranty.  In no event will Google be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, as long as the origin is not misrepresented.
*
* @author: Ricardo Champa
*
*/


public class MyCipher {

    private final static String ALGORITHM ="AES";
    private String mySecret;

    public MyCipher(String mySecret){
        this.mySecret = mySecret;
    }

    public MyCipherData encryptUTF8(String data){
        try{
            byte[] bytes = data.toString().getBytes("utf-8");
            byte[] bytesBase64 = Base64.encodeBase64(bytes);
            return encrypt(bytesBase64);
        }
        catch(Exception e){
            MyLogs.show(e.getMessage());
            return null;
        }

    }

    public String decryptUTF8(byte[] encryptedData, IvParameterSpec iv){
        try {
            byte[] decryptedData = decrypt(encryptedData, iv);
            byte[] decodedBytes = Base64.decodeBase64(decryptedData);
            String restored_data = new String(decodedBytes, Charset.forName("UTF8"));
            return restored_data;
        } catch (Exception e) {
            MyLogs.show(e.getMessage());;
            return null;
        }
    }

    //AES
    private MyCipherData encrypt(byte[] raw, byte[] clear) throws Exception {
        SecretKeySpec skeySpec = new SecretKeySpec(raw, ALGORITHM);
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        //solved using PRNGFixes class
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
        byte[] data = cipher.doFinal(clear);

        AlgorithmParameters params = cipher.getParameters();
        byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
        return new MyCipherData(data, iv);
    }

    private byte[] decrypt(byte[] raw, byte[] encrypted, IvParameterSpec iv) throws Exception {
        SecretKeySpec skeySpec = new SecretKeySpec(raw, ALGORITHM);
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
        byte[] decrypted = cipher.doFinal(encrypted);
        return decrypted;
    }

    private byte[] getKey() throws Exception{
        byte[] keyStart = this.mySecret.getBytes("utf-8");
        KeyGenerator kgen = KeyGenerator.getInstance(ALGORITHM);

        SecureRandom sr = SecureRandom.getInstance("SHA1PRNG","Crypto");
        //      if (android.os.Build.VERSION.SDK_INT >= 17) {
        //          sr = SecureRandom.getInstance("SHA1PRNG","Crypto");
        //      } else {
        //          sr = SecureRandom.getInstance("SHA1PRNG");
        //      }
        sr.setSeed(keyStart);
        kgen.init(128, sr); // 192 and 256 bits may not be available
        SecretKey skey = kgen.generateKey();
        byte[] key = skey.getEncoded();
        return key;

    }
    ////////////////////////////////////////////////////////////
    private MyCipherData encrypt(byte[] data) throws Exception{
        return encrypt(getKey(),data);
    }
    private byte[] decrypt(byte[] encryptedData, IvParameterSpec iv) throws Exception{
        return decrypt(getKey(),encryptedData, iv);
    }
}


如果您正在加密文本文件,那么下面的测试/示例可能很有用。它执行以下操作:

  • 创建字节流,
  • 用AES加密进行包装,
  • 用文本处理将其换行
  • 最后缓冲一下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    // AESdemo

    public class AESdemo extends Activity {
        boolean encryptionIsOn = true;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_aesdemo);
            // needs <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
            String homeDirName = Environment.getExternalStorageDirectory().getAbsolutePath() +
                   "/" + getPackageName();
            File file = new File(homeDirName,"test.txt");
            byte[] keyBytes = getKey("password");

            try {
                File dir = new File(homeDirName);
                if (!dir.exists())
                    dir.mkdirs();
                if (!file.exists())
                    file.createNewFile();

                OutputStreamWriter osw;

                if (encryptionIsOn) {
                    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
                    SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes,"AES");
                    IvParameterSpec ivParameterSpec = new IvParameterSpec(keyBytes);
                    cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);

                    FileOutputStream fos = new FileOutputStream(file);
                    CipherOutputStream cos = new CipherOutputStream(fos, cipher);
                    osw = new OutputStreamWriter(cos,"UTF-8");
                }
                else    // not encryptionIsOn
                    osw = new FileWriter(file);

                BufferedWriter out = new BufferedWriter(osw);
                out.write("This is a test
    "
    );
                out.close();
            }
            catch (Exception e) {
                System.out.println("Encryption Exception"+e);
            }

            ///////////////////////////////////
            try {
                InputStreamReader isr;

                if (encryptionIsOn) {
                    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
                    SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes,"AES");
                    IvParameterSpec ivParameterSpec = new IvParameterSpec(keyBytes);
                    cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);

                    FileInputStream fis = new FileInputStream(file);
                    CipherInputStream cis = new CipherInputStream(fis, cipher);
                    isr = new InputStreamReader(cis,"UTF-8");
                }
                else
                    isr = new FileReader(file);

                BufferedReader in = new BufferedReader(isr);
                String line = in.readLine();
                System.out.println("Text read: <"+line+">");
                in.close();
            }
            catch (Exception e) {
                System.out.println("Decryption Exception"+e);
            }
        }

        private byte[] getKey(String password) throws UnsupportedEncodingException {
            String key ="";
            while (key.length() < 16)
                key += password;
            return key.substring(0, 16).getBytes("UTF-8");
        }
    }


  • 在Android中加密/解密AES

    1
    2
    3
    String encData= encrypt("keykey".getBytes("UTF-16LE"), ("0123000000000215").getBytes("UTF-16LE"));

    String decData= decrypt("keykey",Base64.decode(encData.getBytes("UTF-16LE"), Base64.DEFAULT));

    encrypt function

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    private static String encrypt(byte[] key, byte[] clear) throws Exception
        {
            MessageDigest md = MessageDigest.getInstance("md5");
            byte[] digestOfPassword = md.digest(key);

            SecretKeySpec skeySpec = new SecretKeySpec(digestOfPassword,"AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
            byte[] encrypted = cipher.doFinal(clear);
            return Base64.encodeToString(encrypted,Base64.DEFAULT);
        }

    decrypt function

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    private static String decrypt(String key, byte[] encrypted) throws Exception
        {
            MessageDigest md = MessageDigest.getInstance("md5");
            byte[] digestOfPassword = md.digest(key.getBytes("UTF-16LE"));

            SecretKeySpec skeySpec = new SecretKeySpec(digestOfPassword,"AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec);
            byte[] decrypted = cipher.doFinal(encrypted);
            return new String(decrypted,"UTF-16LE");
        }

    AES在C中加密/解密#

    1
    2
    3
    4
    5
    6
    7
     static void Main(string[] args)
            {
                string enc = encryptAES("0123000000000215","keykey");
                string dec = decryptAES(enc,"keykey");

                Console.ReadKey();
            }

    encrypt function

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     public static string encryptAES(string input, string key)
            {
                var plain = Encoding.Unicode.GetBytes(input);

                // 128 bits
                AesCryptoServiceProvider provider = new AesCryptoServiceProvider();
                provider.KeySize = 128;
                provider.Mode = CipherMode.ECB;
                provider.Padding = PaddingMode.PKCS7;

                provider.Key = CalculateMD5Hash(key);

                var enc = provider.CreateEncryptor().TransformFinalBlock(plain, 0, plain.Length);
                return Convert.ToBase64String(enc);
            }

    decrypt function

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public static string decryptAES(string encryptText, string key)
    {
        byte[] enc = Convert.FromBase64String(encryptText);
        // 128 bits
        AesCryptoServiceProvider provider = new AesCryptoServiceProvider();
        provider.KeySize = 128;
        provider.Mode = CipherMode.ECB;
        provider.Padding = PaddingMode.PKCS7;

        provider.Key = CalculateMD5Hash(key);


        var dec = provider.CreateDecryptor().TransformFinalBlock(enc, 0, enc.Length);
        return Encoding.Unicode.GetString(dec);
    }

    create md5

    1
    2
    3
    4
    5
    6
     public static byte[] CalculateMD5Hash(string input)
            {
                MD5 md5 = MD5.Create();
                byte[] inputBytes = Encoding.Unicode.GetBytes(input);
                return md5.ComputeHash(inputBytes);
            }


    对于aes/cbc/pkcs7加密/解密,只需复制并粘贴以下代码,并用自己的secretkey和iv替换secretkey和iv。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    import java.io.UnsupportedEncodingException;
    import java.security.InvalidAlgorithmParameterException;
    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;

    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;

    import android.util.Base64;


    public class CryptoHandler {

        String SecretKey ="xxxxxxxxxxxxxxxxxxxx";
        String IV ="xxxxxxxxxxxxxxxx";

        private static CryptoHandler instance = null;

        public static CryptoHandler getInstance() {

            if (instance == null) {
                instance = new CryptoHandler();
            }
            return instance;
        }

        public String encrypt(String message) throws NoSuchAlgorithmException,
                NoSuchPaddingException, IllegalBlockSizeException,
                BadPaddingException, InvalidKeyException,
                UnsupportedEncodingException, InvalidAlgorithmParameterException {

            byte[] srcBuff = message.getBytes("UTF8");
            //here using substring because AES takes only 16 or 24 or 32 byte of key
            SecretKeySpec skeySpec = new
            SecretKeySpec(SecretKey.substring(0,32).getBytes(),"AES");
            IvParameterSpec ivSpec = new
            IvParameterSpec(IV.substring(0,16).getBytes());
            Cipher ecipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
            ecipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivSpec);
            byte[] dstBuff = ecipher.doFinal(srcBuff);
            String base64 = Base64.encodeToString(dstBuff, Base64.DEFAULT);
            return base64;
        }

        public String decrypt(String encrypted) throws NoSuchAlgorithmException,
                NoSuchPaddingException, InvalidKeyException,
                InvalidAlgorithmParameterException, IllegalBlockSizeException,
                BadPaddingException, UnsupportedEncodingException {

            SecretKeySpec skeySpec = new
            SecretKeySpec(SecretKey.substring(0,32).getBytes(),"AES");
            IvParameterSpec ivSpec = new
            IvParameterSpec(IV.substring(0,16).getBytes());
            Cipher ecipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
            ecipher.init(Cipher.DECRYPT_MODE, skeySpec, ivSpec);
            byte[] raw = Base64.decode(encrypted, Base64.DEFAULT);
            byte[] originalBytes = ecipher.doFinal(raw);
            String original = new String(originalBytes,"UTF8");
            return original;
        }
    }


    在Android上执行AES加密的简单API。这是与aescrypt库ruby和obj-c相对应的android(具有相同的默认值):

    https://github.com/scottyab/aescrypt-android


    将Bouncy Castle添加到Android项目:https://mvnrepository.com/artifact/org.BouncyCastle/bcprov-jdk16/1.45

    在您的主要活动中添加此行:

    1
    2
    3
    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    public class AESHelper {

        private static final String TAG ="AESHelper";

        public static byte[] encrypt(byte[] data, String initVector, String key) {
            try {
                IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
                Cipher c = Cipher.getInstance("AES/CBC/PKCS5PADDING");
                SecretKeySpec k = new SecretKeySpec(Base64.decode(key, Base64.DEFAULT),"AES");
                c.init(Cipher.ENCRYPT_MODE, k, iv);
                return c.doFinal(data);
            } catch (Exception e) {
                e.printStackTrace();
            }

            return null;
        }

        public static byte[] decrypt(byte[] data, String initVector, String key) {
            try {
                IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
                Cipher c = Cipher.getInstance("AES/CBC/PKCS5PADDING");
                SecretKeySpec k = new SecretKeySpec(Base64.decode(key, Base64.DEFAULT),"AES");
                c.init(Cipher.DECRYPT_MODE, k, iv);
                return c.doFinal(data);
            } catch (Exception e) {
                e.printStackTrace();
            }

            return null;
        }

        public static String keyGenerator() throws NoSuchAlgorithmException {
            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
            keyGenerator.init(192);

            return Base64.encodeToString(keyGenerator.generateKey().getEncoded(),
                    Base64.DEFAULT);
        }
    }