Skip to content

Commit 000b086

Browse files
committed
优化3DES加解密工具类,增加AES加解密工具类和数据转换工具类
1 parent 9c5c9be commit 000b086

File tree

6 files changed

+1114
-94
lines changed

6 files changed

+1114
-94
lines changed

app/src/main/java/com/fantasy/blogdemo/crypto/CryptoActivity.java

+130-38
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,21 @@
77
import android.util.Log;
88
import android.view.View;
99
import android.widget.EditText;
10+
import android.widget.RadioGroup;
1011
import android.widget.TextView;
1112

1213
import com.fantasy.blogdemo.Constant;
1314
import com.fantasy.blogdemo.R;
1415
import com.fantasy.blogdemo.base.BaseActivity;
16+
import com.fantasy.blogdemo.crypto.utils.AESUtils;
1517
import com.fantasy.blogdemo.crypto.utils.CryptoHelper;
1618
import com.fantasy.blogdemo.crypto.utils.TripleDESUtils;
1719

1820
/**
1921
* 加解密
2022
* <pre>
2123
* author : Fantasy
22-
* version : 1.0, 2019-07-10
24+
* version : 1.1, 2019-07-12
2325
* since : 1.0, 2019-07-10
2426
* </pre>
2527
*/
@@ -29,6 +31,9 @@ public class CryptoActivity extends BaseActivity implements View.OnClickListener
2931
private EditText mEtData;
3032
private EditText mEtResult;
3133

34+
private int mEncryptionModeCheckedId;
35+
private int mOutputModeCheckedId;
36+
3237
/**
3338
* 打开“加解密”模块
3439
*
@@ -54,14 +59,27 @@ private void bindEvent() {
5459
mEtData = findViewById(R.id.et_crypto_data);
5560
mEtResult = findViewById(R.id.et_crypto_result);
5661
findViewById(R.id.btn_crypto_md5).setOnClickListener(this);
57-
findViewById(R.id.btn_crypto_3des_ecb_encrypt).setOnClickListener(this);
58-
findViewById(R.id.btn_crypto_3des_ecb_decrypt).setOnClickListener(this);
59-
findViewById(R.id.btn_crypto_3des_cbc_encrypt).setOnClickListener(this);
60-
findViewById(R.id.btn_crypto_3des_cbc_decrypt).setOnClickListener(this);
62+
findViewById(R.id.btn_crypto_3des_encrypt).setOnClickListener(this);
63+
findViewById(R.id.btn_crypto_3des_decrypt).setOnClickListener(this);
64+
findViewById(R.id.btn_crypto_aes_encrypt).setOnClickListener(this);
65+
findViewById(R.id.btn_crypto_aes_decrypt).setOnClickListener(this);
66+
((RadioGroup) findViewById(R.id.rg_crypto_encryption_mode)).setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
67+
@Override
68+
public void onCheckedChanged(RadioGroup group, int checkedId) {
69+
mEncryptionModeCheckedId = checkedId;
70+
}
71+
});
72+
((RadioGroup) findViewById(R.id.rg_crypto_output_mode)).setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
73+
@Override
74+
public void onCheckedChanged(RadioGroup group, int checkedId) {
75+
mOutputModeCheckedId = checkedId;
76+
}
77+
});
6178
}
6279

6380
private void initData() {
64-
mEtKey.requestFocus();
81+
mEncryptionModeCheckedId = R.id.rb_crypto_ecb;
82+
mOutputModeCheckedId = R.id.rb_crypto_base64;
6583
}
6684

6785
@Override
@@ -79,44 +97,118 @@ public void onClick(View v) {
7997
Log.d(Constant.TAG, "data : " + data + " result : " + result);
8098
}
8199
break;
82-
case R.id.btn_crypto_3des_ecb_encrypt: // 3DES(ECB模式)加密
83-
if (checkKey() && checkData()) {
84-
String key = mEtKey.getText().toString(); // 密钥长度16位或者24位
85-
String data = mEtData.getText().toString();
86-
String result = TripleDESUtils.encryptECB(key, data);
87-
mEtResult.setText(result);
88-
Log.d(Constant.TAG, "data : " + data + " result : " + result + " key : " + key);
100+
case R.id.btn_crypto_3des_encrypt: // 3DES加密
101+
String key = mEtKey.getText().toString(); // 密钥长度16位、24位
102+
String iv = mEtIv.getText().toString(); // IV偏移量的长度必须为8位
103+
String data = mEtData.getText().toString();
104+
String transformation;
105+
String result;
106+
if (mEncryptionModeCheckedId == R.id.rb_crypto_ecb) {
107+
transformation = "DESede/ECB/PKCS5Padding";
108+
if (checkKey() && checkData()) {
109+
if (mOutputModeCheckedId == R.id.rb_crypto_base64) {
110+
result = TripleDESUtils.encryptBase64(data, key, transformation, null);
111+
} else {
112+
result = TripleDESUtils.encryptHex(data, key, transformation, null);
113+
}
114+
mEtResult.setText(result);
115+
Log.d(Constant.TAG, "data : " + data + " result : " + result + " key : " + key);
116+
}
117+
} else {
118+
transformation = "DESede/CBC/PKCS5Padding";
119+
if (checkKey() && checkIV() && checkData()) {
120+
if (mOutputModeCheckedId == R.id.rb_crypto_base64) {
121+
result = TripleDESUtils.encryptBase64(data, key, transformation, iv);
122+
} else {
123+
result = TripleDESUtils.encryptHex(data, key, transformation, iv);
124+
}
125+
mEtResult.setText(result);
126+
Log.d(Constant.TAG, "data : " + data + " result : " + result + " key : " + key + " iv : " + iv);
127+
}
89128
}
90129
break;
91-
case R.id.btn_crypto_3des_ecb_decrypt: // 3DES(ECB模式)解密
92-
if (checkKey() && checkData()) {
93-
String key = mEtKey.getText().toString(); // 密钥长度16位或者24位
94-
String data = mEtData.getText().toString();
95-
String result = TripleDESUtils.decryptECB(key, data);
96-
mEtResult.setText(result);
97-
Log.d(Constant.TAG, "data : " + data + " result : " + result + " key : " + key);
130+
case R.id.btn_crypto_3des_decrypt: // 3DES解密
131+
key = mEtKey.getText().toString(); // 密钥长度16位、24位
132+
iv = mEtIv.getText().toString(); // IV偏移量的长度必须为8位
133+
data = mEtData.getText().toString();
134+
if (mEncryptionModeCheckedId == R.id.rb_crypto_ecb) {
135+
transformation = "DESede/ECB/PKCS5Padding";
136+
if (checkKey() && checkData()) {
137+
if (mOutputModeCheckedId == R.id.rb_crypto_base64) {
138+
result = TripleDESUtils.decryptBase64(data, key, transformation, null);
139+
} else {
140+
result = TripleDESUtils.decryptHex(data, key, transformation, null);
141+
}
142+
mEtResult.setText(result);
143+
Log.d(Constant.TAG, "data : " + data + " result : " + result + " key : " + key);
144+
}
145+
} else {
146+
transformation = "DESede/CBC/PKCS5Padding";
147+
if (checkKey() && checkIV() && checkData()) {
148+
if (mOutputModeCheckedId == R.id.rb_crypto_base64) {
149+
result = TripleDESUtils.decryptBase64(data, key, transformation, iv);
150+
} else {
151+
result = TripleDESUtils.decryptHex(data, key, transformation, iv);
152+
}
153+
mEtResult.setText(result);
154+
Log.d(Constant.TAG, "data : " + data + " result : " + result + " key : " + key + " iv : " + iv);
155+
}
98156
}
99157
break;
100-
case R.id.btn_crypto_3des_cbc_encrypt: // 3DES(CBC模式)加密
101-
if (checkKey() && checkIV() && checkData()) {
102-
String key = mEtKey.getText().toString(); // 密钥长度16位或者24位
103-
String iv = mEtIv.getText().toString(); // IV偏移量的长度必须为8位
104-
String data = mEtData.getText().toString();
105-
String result = TripleDESUtils.encryptCBC(key, iv, data);
106-
mEtResult.setText(result);
107-
Log.d(Constant.TAG, "data : " + data + " result : " + result
108-
+ " key : " + key + " iv : " + iv);
158+
case R.id.btn_crypto_aes_encrypt: // AES加密
159+
key = mEtKey.getText().toString(); // 密钥长度16位、24位、32位
160+
iv = mEtIv.getText().toString(); // IV偏移量的长度必须为16位
161+
data = mEtData.getText().toString();
162+
if (mEncryptionModeCheckedId == R.id.rb_crypto_ecb) {
163+
transformation = "AES/ECB/PKCS5Padding";
164+
if (checkKey() && checkData()) {
165+
if (mOutputModeCheckedId == R.id.rb_crypto_base64) {
166+
result = AESUtils.encryptBase64(data, key, transformation, null);
167+
} else {
168+
result = AESUtils.encryptHex(data, key, transformation, null);
169+
}
170+
mEtResult.setText(result);
171+
Log.d(Constant.TAG, "data : " + data + " result : " + result + " key : " + key);
172+
}
173+
} else {
174+
transformation = "AES/CBC/PKCS5Padding";
175+
if (checkKey() && checkIV() && checkData()) {
176+
if (mOutputModeCheckedId == R.id.rb_crypto_base64) {
177+
result = AESUtils.encryptBase64(data, key, transformation, iv);
178+
} else {
179+
result = AESUtils.encryptHex(data, key, transformation, iv);
180+
}
181+
mEtResult.setText(result);
182+
Log.d(Constant.TAG, "data : " + data + " result : " + result + " key : " + key + " iv : " + iv);
183+
}
109184
}
110185
break;
111-
case R.id.btn_crypto_3des_cbc_decrypt: // 3DES(CBC模式)解密
112-
if (checkKey() && checkIV() && checkData()) {
113-
String key = mEtKey.getText().toString(); // 密钥长度16位或者24位
114-
String iv = mEtIv.getText().toString(); // IV偏移量的长度必须为8位
115-
String data = mEtData.getText().toString();
116-
String result = TripleDESUtils.decryptCBC(key, iv, data);
117-
mEtResult.setText(result);
118-
Log.d(Constant.TAG, "data : " + data + " result : " + result
119-
+ " key : " + key + " iv : " + iv);
186+
case R.id.btn_crypto_aes_decrypt: // AES解密
187+
key = mEtKey.getText().toString(); // 密钥长度16位或者24位
188+
iv = mEtIv.getText().toString(); // IV偏移量的长度必须为8位
189+
data = mEtData.getText().toString();
190+
if (mEncryptionModeCheckedId == R.id.rb_crypto_ecb) {
191+
transformation = "AES/ECB/PKCS5Padding";
192+
if (checkKey() && checkData()) {
193+
if (mOutputModeCheckedId == R.id.rb_crypto_base64) {
194+
result = AESUtils.decryptBase64(data, key, transformation, null);
195+
} else {
196+
result = AESUtils.decryptHex(data, key, transformation, null);
197+
}
198+
mEtResult.setText(result);
199+
Log.d(Constant.TAG, "data : " + data + " result : " + result + " key : " + key);
200+
}
201+
} else {
202+
transformation = "AES/CBC/PKCS5Padding";
203+
if (checkKey() && checkIV() && checkData()) {
204+
if (mOutputModeCheckedId == R.id.rb_crypto_base64) {
205+
result = AESUtils.decryptBase64(data, key, transformation, iv);
206+
} else {
207+
result = AESUtils.decryptHex(data, key, transformation, iv);
208+
}
209+
mEtResult.setText(result);
210+
Log.d(Constant.TAG, "data : " + data + " result : " + result + " key : " + key + " iv : " + iv);
211+
}
120212
}
121213
break;
122214
default:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
package com.fantasy.blogdemo.crypto.utils;
2+
3+
import android.util.Base64;
4+
5+
import com.fantasy.blogdemo.utils.ConvertUtils;
6+
7+
import javax.crypto.Cipher;
8+
import javax.crypto.SecretKey;
9+
import javax.crypto.spec.IvParameterSpec;
10+
import javax.crypto.spec.SecretKeySpec;
11+
12+
/**
13+
* AES加解密工具类
14+
* <pre>
15+
* author : Fantasy
16+
* version : 1.0, 2019-07-12
17+
* since : 1.0, 2019-07-12
18+
* </pre>
19+
*/
20+
public class AESUtils {
21+
private static final String CHARSET = "UTF-8";
22+
23+
/**
24+
* 加密,输出Base64字符串密文
25+
*
26+
* @param data 明文
27+
* @param key 密钥
28+
* @param transformation 类型,格式为:加密算法/加密模式/填充方式,举例:AES/CBC/PKCS5Padding,
29+
* 相关取值可以查看下列两个文档:
30+
* <ul>
31+
* <li><a href="https://docs.oracle.com/javase/8/docs/api">JavaSE 8 API</a>
32+
* 中的 javax.crypto.Cipher</li>
33+
* <li><a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Cipher">
34+
* Standard Algorithm Name Documentation</a></li>
35+
* </ul>
36+
* @param iv 偏移量,ECB模式不需要,传null
37+
* @return 密文
38+
* @throws Exception 异常
39+
*/
40+
public static String encryptBase64(String data, String key, String transformation, String iv) throws Exception {
41+
return Base64.encodeToString(handle(data.getBytes(CHARSET), key, transformation, iv, true), Base64.NO_WRAP);
42+
}
43+
44+
/**
45+
* 解密,密文为Base64字符串
46+
*
47+
* @param data 密文
48+
* @param key 密钥
49+
* @param transformation 类型,格式为:加密算法/加密模式/填充方式,举例:AES/CBC/PKCS5Padding,
50+
* 相关取值可以查看下列两个文档:
51+
* <ul>
52+
* <li><a href="https://docs.oracle.com/javase/8/docs/api">JavaSE 8 API</a>
53+
* 中的 javax.crypto.Cipher</li>
54+
* <li><a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Cipher">
55+
* Standard Algorithm Name Documentation</a></li>
56+
* </ul>
57+
* @param iv 偏移量,ECB模式不需要,传null
58+
* @return 明文
59+
* @throws Exception 异常
60+
*/
61+
public static String decryptBase64(String data, String key, String transformation, String iv) throws Exception {
62+
return new String(handle(Base64.decode(data, Base64.NO_WRAP), key, transformation, iv, false), CHARSET);
63+
}
64+
65+
/**
66+
* 加密,输出十六进制字符串密文
67+
*
68+
* @param data 明文
69+
* @param key 密钥
70+
* @param transformation 类型,格式为:加密算法/加密模式/填充方式,举例:AES/CBC/PKCS5Padding,
71+
* 相关取值可以查看下列两个文档:
72+
* <ul>
73+
* <li><a href="https://docs.oracle.com/javase/8/docs/api">JavaSE 8 API</a>
74+
* 中的 javax.crypto.Cipher</li>
75+
* <li><a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Cipher">
76+
* Standard Algorithm Name Documentation</a></li>
77+
* </ul>
78+
* @param iv 偏移量,ECB模式不需要,传null
79+
* @return 密文
80+
* @throws Exception 异常
81+
*/
82+
public static String encryptHex(String data, String key, String transformation, String iv) throws Exception {
83+
return ConvertUtils.bytesToHexString(handle(data.getBytes(CHARSET), key, transformation, iv, true));
84+
}
85+
86+
/**
87+
* 解密,密文为十六进制字符串
88+
*
89+
* @param data 密文
90+
* @param key 密钥
91+
* @param transformation 类型,格式为:加密算法/加密模式/填充方式,举例:AES/CBC/PKCS5Padding,
92+
* 相关取值可以查看下列两个文档:
93+
* <ul>
94+
* <li><a href="https://docs.oracle.com/javase/8/docs/api">JavaSE 8 API</a>
95+
* 中的 javax.crypto.Cipher</li>
96+
* <li><a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Cipher">
97+
* Standard Algorithm Name Documentation</a></li>
98+
* </ul>
99+
* @param iv 偏移量,ECB模式不需要,传null
100+
* @return 明文
101+
* @throws Exception 异常
102+
*/
103+
public static String decryptHex(String data, String key, String transformation, String iv) throws Exception {
104+
return new String(handle(ConvertUtils.hexStringToBytes(data), key, transformation, iv, false), CHARSET);
105+
}
106+
107+
/**
108+
* 处理数据,加密或解密
109+
*
110+
* @param data 数据
111+
* @param key 密钥
112+
* @param transformation 类型,格式为:加密算法/加密模式/填充方式,举例:<i>AES/CBC/PKCS5Padding</i>。<br/>
113+
* 相关取值可以查看下列两个文档:
114+
* <ul>
115+
* <li><a href="https://docs.oracle.com/javase/8/docs/api">JavaSE 8 API</a>
116+
* 中的 javax.crypto.Cipher</li>
117+
* <li><a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Cipher">
118+
* Standard Algorithm Name Documentation</a></li>
119+
* </ul>
120+
* @param iv 偏移量,ECB模式不需要,传null
121+
* @param isEncrypt 如果是加密,则为true;如果为解密,则为false
122+
* @return 加密后或解密后的字节数组
123+
* @throws Exception 异常
124+
*/
125+
private static byte[] handle(byte[] data, String key, String transformation, String iv,
126+
boolean isEncrypt) throws Exception {
127+
SecretKey secretKey = new SecretKeySpec(key.getBytes(CHARSET), "AES"); // 构造密钥
128+
Cipher cipher = Cipher.getInstance(transformation);
129+
if (iv == null || iv.length() == 0) {
130+
cipher.init(isEncrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, secretKey);
131+
} else {
132+
IvParameterSpec ips = new IvParameterSpec(iv.getBytes(CHARSET));
133+
cipher.init(isEncrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, secretKey, ips);
134+
}
135+
return cipher.doFinal(data);
136+
}
137+
138+
}

0 commit comments

Comments
 (0)