android中AES加解密的使用方法

今天在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加解密成功了

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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值