|
11 | 11 | import java.io.UnsupportedEncodingException; |
12 | 12 | import java.security.MessageDigest; |
13 | 13 | import java.security.NoSuchAlgorithmException; |
| 14 | +import java.security.SecureRandom; |
14 | 15 | import java.security.cert.CertificateEncodingException; |
15 | 16 | import java.security.cert.CertificateException; |
16 | 17 | import java.security.cert.CertificateFactory; |
17 | 18 | import java.security.cert.X509Certificate; |
18 | 19 | import java.util.Arrays; |
| 20 | +import java.util.Random; |
19 | 21 |
|
20 | 22 | import javax.crypto.Cipher; |
21 | 23 | import javax.crypto.SecretKey; |
| 24 | +import javax.crypto.spec.IvParameterSpec; |
22 | 25 | import javax.crypto.spec.SecretKeySpec; |
23 | 26 |
|
24 | 27 | /** |
|
27 | 30 |
|
28 | 31 | public class AndroidStringObfuscator { |
29 | 32 |
|
| 33 | + private static final int LENGTH = 16; |
30 | 34 | private static final String CODIFICATION = "UTF-8"; |
31 | | - private static final String TRANSFORMATION = "AES/ECB/PKCS5Padding"; |
| 35 | + private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding"; |
32 | 36 | private static final char[] hexArray = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; |
33 | 37 | private static final String TAG = AndroidStringObfuscator.class.getSimpleName(); |
34 | 38 | private static Context context; |
| 39 | + private static byte[] iv = new byte[0]; |
35 | 40 |
|
36 | 41 | public static void init(Context c) { |
37 | 42 | context = c; |
@@ -100,19 +105,21 @@ private static SecretKey generateKey(String key) throws NoSuchAlgorithmException |
100 | 105 | } |
101 | 106 |
|
102 | 107 | private static String encrypt(String message, String key) throws Exception { |
| 108 | + buildIvParam(message, key); |
103 | 109 | byte[] data = message.getBytes(CODIFICATION); |
104 | 110 | Cipher cipher = Cipher.getInstance(TRANSFORMATION); |
105 | | - cipher.init(Cipher.ENCRYPT_MODE, generateKey(key)); |
| 111 | + cipher.init(Cipher.ENCRYPT_MODE, generateKey(key), new IvParameterSpec(iv)); |
106 | 112 | byte[] encryptData = cipher.doFinal(data); |
107 | 113 |
|
108 | 114 | return byteArrayToHexString(encryptData); |
109 | 115 | } |
110 | 116 |
|
111 | 117 | private static String decrypt(String message, String key) throws Exception { |
| 118 | + buildIvParam(message, key); |
112 | 119 | byte[] tmp = hexStringToByteArray(message); |
113 | 120 | SecretKeySpec spec = new SecretKeySpec(generateKey(key).getEncoded(), "AES"); |
114 | 121 | Cipher cipher = Cipher.getInstance(TRANSFORMATION); |
115 | | - cipher.init(Cipher.DECRYPT_MODE, spec); |
| 122 | + cipher.init(Cipher.DECRYPT_MODE, spec, new IvParameterSpec(iv)); |
116 | 123 |
|
117 | 124 | String result = new String(cipher.doFinal(tmp), CODIFICATION); |
118 | 125 | return result; |
@@ -201,4 +208,23 @@ public static String decryptString(String value) { |
201 | 208 | } |
202 | 209 | return null; |
203 | 210 | } |
| 211 | + |
| 212 | + private static void buildIvParam(String message, String key) { |
| 213 | + if (iv.length == 0) { |
| 214 | + iv = new byte[LENGTH]; |
| 215 | + int index = randomNumber(key.length()); |
| 216 | + System.arraycopy(key.getBytes(), index, iv, 0, LENGTH); |
| 217 | + |
| 218 | + try { |
| 219 | + return decrypt(message, hash); |
| 220 | + } catch (Exception e) { |
| 221 | + e.printStackTrace(); |
| 222 | + } |
| 223 | + } |
| 224 | + } |
| 225 | + |
| 226 | + private static int randomNumber(int length){ |
| 227 | + int value = new Random().nextInt(length) + length - 2 - length; |
| 228 | + return value; |
| 229 | + } |
204 | 230 | } |
0 commit comments