android中AES加解密的使用方法

时间:2024-03-27 19:01:06

今天在android项目中使用AES对数据进行加解密,遇到了很多问题,网上也找了很多资料,也不行。不过最后还是让我给搞出来了,这里把这个记录下来,不要让别人走我的弯路,因为网上绝大多数的例子都是行不通的。好了,接下来开始讲解

1、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
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
package com.example.cheng.aesencrypt;
 
import android.text.TextUtils;
 
import java.security.NoSuchAlgorithmException;
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;
 
 
/**
 * class description here
 *
 * @author cheng
 * @version 1.0.0
 * @since 2016-11-02
 */
public class Aes {
 
 private static final String SHA1PRNG = "SHA1PRNG"; // SHA1PRNG 强随机种子算法, 要区别4.2以上版本的调用方法
 private static final String IV = "qws871bz73msl9x8";
 private static final String AES = "AES"; //AES 加密
 private static final String CIPHERMODE = "AES/CBC/PKCS5Padding"; //algorithm/mode/padding
 
 /**
 * 加密
 */
 public static String encrypt(String key, String cleartext) {
 if (TextUtils.isEmpty(cleartext)) {
  return cleartext;
 }
 try {
  byte[] result = encrypt(key, cleartext.getBytes());
  return parseByte2HexStr(result);
 } catch (Exception e) {
  e.printStackTrace();
 }
 return null;
 }
 
 /**
 * 加密
 */
 public static byte[] encrypt(String key, byte[] clear) throws Exception {
 byte[] raw = getRawKey(key.getBytes());
 SecretKeySpec skeySpec = new SecretKeySpec(raw, AES);
 Cipher cipher = Cipher.getInstance(CIPHERMODE);
 cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(new byte[cipher.getBlockSize()]));
 byte[] encrypted = cipher.doFinal(clear);
 return encrypted;
 }
 
 /**
 * 解密
 */
 public static String decrypt(String key, String encrypted) {
 if (TextUtils.isEmpty(encrypted)) {
  return encrypted;
 }
 try {
  byte[] enc = parseHexStr2Byte(encrypted);
  byte[] result = decrypt(key, enc);
  return new String(result);
 } catch (Exception e) {
  e.printStackTrace();
 }
 return null;
 }
 
 /**
 * 解密
 */
 public static byte[] decrypt(String key, byte[] encrypted) throws Exception {
 byte[] raw = getRawKey(key.getBytes());
 SecretKeySpec skeySpec = new SecretKeySpec(raw, AES);
 Cipher cipher = Cipher.getInstance(CIPHERMODE);
 cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(new byte[cipher.getBlockSize()]));
 byte[] decrypted = cipher.doFinal(encrypted);
 return decrypted;
 }
 
 /**
 * 生成随机数,可以当做动态的**
 * 加密和解密的**必须一致,不然将不能解密
 */
 public static String generateKey() {
 try {
  SecureRandom secureRandom = SecureRandom.getInstance(SHA1PRNG);
  byte[] key = new byte[20];
  secureRandom.nextBytes(key);
  return toHex(key);
 } catch (NoSuchAlgorithmException e) {
  e.printStackTrace();
 }
 return null;
 }
 
 /**
 * 对**进行处理
 */
 public static byte[] getRawKey(byte[] seed) throws Exception {
 KeyGenerator kgen = KeyGenerator.getInstance(AES);
 //for android
 SecureRandom sr = null;
 // 在4.2以上版本中,SecureRandom获取方式发生了改变
 if (android.os.Build.VERSION.SDK_INT >= 17) {
  sr = SecureRandom.getInstance(SHA1PRNG, "Crypto");
 } else {
  sr = SecureRandom.getInstance(SHA1PRNG);
 }
 // for Java
 // secureRandom = SecureRandom.getInstance(SHA1PRNG);
 sr.setSeed(seed);
 kgen.init(128, sr); //256 bits or 128 bits,192bits
 //AES中128位**版本有10个加密循环,192比特**版本有12个加密循环,256比特**版本则有14个加密循环。
 SecretKey skey = kgen.generateKey();
 byte[] raw = skey.getEncoded();
 return raw;
 }
 
 /**
 * 二进制转字符
 */
 public static String toHex(byte[] buf) {
 if (buf == null)
  return "";
 StringBuffer result = new StringBuffer(2 * buf.length);
 for (int i = 0; i < buf.length; i++) {
  appendHex(result, buf[i]);
 }
 return result.toString();
 }
 
 private static void appendHex(StringBuffer sb, byte b) {
 sb.append(IV.charAt((b >> 4) & 0x0f)).append(IV.charAt(b & 0x0f));
 }
 
 /**
 * 将二进制转换成16进制
 *
 * @param buf
 * @return
 */
 public static String parseByte2HexStr(byte buf[]) {
 StringBuilder sb = new StringBuilder();
 for (int i = 0; i < buf.length; i++) {
  String hex = Integer.toHexString(buf[i] & 0xFF);
  if (hex.length() == 1) {
  hex = '0' + hex;
  }
  sb.append(hex.toUpperCase());
 }
 return sb.toString();
 }
 
 /**
 * 将16进制转换为二进制
 *
 * @param hexStr
 * @return
 */
 public static byte[] parseHexStr2Byte(String hexStr) {
 if (hexStr.length() < 1)
  return null;
 byte[] result = new byte[hexStr.length() / 2];
 for (int i = 0; i < hexStr.length() / 2; i++) {
  int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
  int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2),
   16);
  result[i] = (byte) (high * 16 + low);
 }
 return result;
 }
}

2、mainActivity和layout文件如下:

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
package com.example.cheng.aesencrypt;
 
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
 
 
public class MainActivity extends AppCompatActivity {
 private EditText mInputET;
 private TextView mShowEncryputTV;
 private TextView mShowInputTV;
 private static final String PASSWORD_STRING = "12345678";
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 mInputET = (EditText) findViewById(R.id.ase_input);
 mShowEncryputTV = (TextView) findViewById(R.id.show_oringe_encrypt);
 mShowInputTV = (TextView) findViewById(R.id.show_ase_encrypt);
 }
 
 /**
 * 加密
 *
 * @param view
 */
 public void encrypt(View view) {
 String inputString = mInputET.getText().toString().trim();
 if (inputString.length() == 0) {
  Toast.makeText(this, "请输入要加密的内容", Toast.LENGTH_SHORT).show();
  return;
 }
 String encryStr = Aes.encrypt(PASSWORD_STRING, inputString);
 mShowInputTV.setText(encryStr);
 }
 
 /**
 * 解密
 *
 * @param view
 */
 public void decrypt(View view) {
 String encryptString = mShowInputTV.getText().toString().trim();
 if (encryptString.length() == 0) {
  Toast.makeText(this, "解密字符串不能为空", Toast.LENGTH_SHORT).show();
  return;
 }
 String decryStr = Aes.decrypt(PASSWORD_STRING, encryptString);
 mShowEncryputTV.setText(decryStr);
 }
}

layout文件

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
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:id="@+id/activity_main"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:gravity="center_vertical"
 android:orientation="vertical"
 android:paddingBottom="@dimen/activity_vertical_margin"
 android:paddingLeft="@dimen/activity_horizontal_margin"
 android:paddingRight="@dimen/activity_horizontal_margin"
 android:paddingTop="@dimen/activity_vertical_margin"
 tools:context="com.example.cheng.aesencrypt.MainActivity">
 
 
 <EditText
 android:id="@+id/ase_input"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:hint="输入要加密的内容" />
 
 <Button
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:onClick="encrypt"
 android:text="点击进行ASE加密" />
 
 <TextView
 android:id="@+id/show_ase_encrypt"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:layout_marginTop="10dp"
 android:text="显示加密后的内容" />
 
 <Button
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:onClick="decrypt"
 android:text="点击进行ASE解密" />
 
 <TextView
 android:id="@+id/show_oringe_encrypt"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_marginTop="10dp"
 android:text="显示加密后的内容" />
 
</LinearLayout>

3、最后的效果如下:

1)、是一个输入框,输入钥加密的字符串;

2)、点击“AES加密”按钮后生产的加密字符串;

3)、点击“AES解密”按钮后,对加密字符串进行解密,然后在3处看到解密后的字符串,可以看到加密字符串和解密字符串相同,所以AES加解密成功了

android中AES加解密的使用方法

4、总结

要用真机测试,模拟器是不行的,具体原因没去研究;
点击获取本例的github地址:
也可以通过android studio直接git下来,git地址为https://github.com/chenguo4930/AndroidAES.git
其中也还有DES、RSA的加解密demo的github地址为https://github.com/chenguo4930/EncodeDemo
git地址为: https://github.com/chenguo4930/EncodeDemo.git