· 9 years ago · Oct 01, 2016, 12:41 PM
1import android.annotation.TargetApi;
2import android.os.Build;
3import android.util.Base64;
4
5import com.shikshaatoday.app.BuildConfig;
6
7import java.io.UnsupportedEncodingException;
8import java.math.BigInteger;
9import java.nio.charset.StandardCharsets;
10import java.security.InvalidAlgorithmParameterException;
11import java.security.InvalidKeyException;
12import java.security.NoSuchAlgorithmException;
13import java.security.SecureRandom;
14import java.security.spec.InvalidKeySpecException;
15import java.security.spec.KeySpec;
16
17import javax.crypto.BadPaddingException;
18import javax.crypto.Cipher;
19import javax.crypto.IllegalBlockSizeException;
20import javax.crypto.NoSuchPaddingException;
21import javax.crypto.SecretKey;
22import javax.crypto.SecretKeyFactory;
23import javax.crypto.spec.IvParameterSpec;
24import javax.crypto.spec.PBEKeySpec;
25import javax.crypto.spec.SecretKeySpec;
26
27/**
28 * @author Rugved
29 */
30public class AesUtil {
31 private final int keySize;
32 private final int iterationCount;
33 private final Cipher cipher;
34 public static final String SALT = "00000000000000000000000000000000";//32 chars
35 public static final String INITIAL_VECTOR = "00000000000000000000000000000000";//32 chars
36 public static final int AES_KEY_LENGTH = 128;
37 public static final int AES_KEY_GENERATION_ITERATION_COUNT = 100;
38 public static final String AES_PASSPHRASE = "0000000000000000";// 16 chars
39 final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
40
41 public AesUtil(int keySize, int iterationCount) {
42 this.keySize = keySize;
43 this.iterationCount = iterationCount;
44 try {
45 cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
46 } catch (NoSuchAlgorithmException e) {
47 throw fail(e);
48 } catch (NoSuchPaddingException e) {
49 throw fail(e);
50 }
51 }
52
53 public String encrypt(String salt, String iv, String passphrase, String plaintext) {
54 try {
55 SecretKey key = generateKey(salt, passphrase);
56 byte[] encrypted = doFinal(Cipher.ENCRYPT_MODE, key, iv, plaintext.getBytes("UTF-8"));
57 return base64(encrypted);
58 } catch (UnsupportedEncodingException e) {
59 throw fail(e);
60 }
61 }
62
63 public String decrypt(String salt, String iv, String passphrase, String ciphertext) {
64 try {
65 SecretKey key = generateKey(salt, passphrase);
66 byte[] decrypted = doFinal(Cipher.DECRYPT_MODE, key, iv, base64(ciphertext));
67 return new String(decrypted, "UTF-8");
68 } catch (UnsupportedEncodingException e) {
69 throw fail(e);
70 }
71 }
72
73 private byte[] doFinal(int encryptMode, SecretKey key, String iv, byte[] bytes) {
74 byte[] result = null;
75 try {
76 byte[] ivArray = hexStringtoByteArray(iv);
77 // Log.d("byte[] of IV", ivArray.toString());
78 cipher.init(encryptMode, key, new IvParameterSpec(ivArray));
79 result = cipher.doFinal(bytes);
80 } catch (InvalidKeyException e) {
81 throw fail(e);
82 } catch (InvalidAlgorithmParameterException e) {
83 e.printStackTrace();
84 } catch (IllegalBlockSizeException e) {
85 e.printStackTrace();
86 } catch (BadPaddingException e) {
87 e.printStackTrace();
88 }
89 return result;
90 }
91
92 private SecretKey generateKey(String salt, String passphrase) {
93 SecretKey key = null;
94 try {
95 SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
96 KeySpec spec = new PBEKeySpec(passphrase.toCharArray(), hexStringtoByteArray(salt), iterationCount, keySize);
97 key = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
98 } catch (NoSuchAlgorithmException e) {
99 throw fail(e);
100 } catch (InvalidKeySpecException e) {
101 e.printStackTrace();
102 }
103 return key;
104 }
105
106 public static String random(int length) {
107 byte[] salt = new byte[length];
108 new SecureRandom().nextBytes(salt);
109 return hexByteArrayToString(salt);
110 }
111
112 public static String base64(byte[] bytes) {
113 return Base64.encodeToString(bytes, Base64.DEFAULT);
114 }
115
116 public static byte[] base64(String str) {
117 return Base64.decode(str, Base64.DEFAULT);
118 }
119
120 public static String hexByteArrayToString(byte[] bytes) {
121 char[] hexChars = new char[bytes.length * 2];
122 for (int j = 0; j < bytes.length; j++) {
123 int v = bytes[j] & 0xFF;
124 hexChars[j * 2] = hexArray[v >>> 4];
125 hexChars[j * 2 + 1] = hexArray[v & 0x0F];
126 }
127 return new String(hexChars);
128 // return Hex.encodeHexString(bytes);
129 }
130
131 public static byte[] hexStringtoByteArray(String str) {
132 int len = str.length();
133 byte[] data = new byte[len / 2];
134 for (int i = 0; i < len; i += 2) {
135 data[i / 2] = (byte) ((Character.digit(str.charAt(i), 16) << 4) + Character.digit(str.charAt(i + 1), 16));
136 }
137 return data;
138 // try {
139 // return Hex.decodeHex(str.toCharArray());
140 // } catch (DecoderException e) {
141 // throw new IllegalStateException(e);
142 // }
143
144 }
145
146 @TargetApi(Build.VERSION_CODES.KITKAT)
147 public String toHex(String arg) {
148 return String.format("%040x", new BigInteger(1, arg.getBytes(StandardCharsets.UTF_8)));
149 }
150
151 private IllegalStateException fail(Exception e) {
152 return new IllegalStateException(e);
153 }
154
155}