在各种系统中,我们都难免会要用到加密。加密方式分成可还原密文和不可还原密文两种,可还原密文用得比较普遍、比较多的就是DES算法了,不可还原的比较多的就是MD5了。本文提供两种算法的相应java实现。有部分函数参考网络实现
1
package com.resoft.util;
2
3
import java.io.UnsupportedEncodingException;
4
import java.security.InvalidKeyException;
5
import java.security.MessageDigest;
6
import java.security.NoSuchAlgorithmException;
7
import java.security.SecureRandom;
8
import java.security.spec.InvalidKeySpecException;
9
10
import javax.crypto.BadPaddingException;
11
import javax.crypto.Cipher;
12
import javax.crypto.IllegalBlockSizeException;
13
import javax.crypto.NoSuchPaddingException;
14
import javax.crypto.SecretKey;
15
import javax.crypto.SecretKeyFactory;
16
import javax.crypto.spec.DESKeySpec;
17
18
import sun.misc.BASE64Encoder;
19
20
/**
21
* 安全加密类
22
*
23
* @date 2007-10-31
24
* @author yayagepei
25
*
26
*/
27
public class SecurityEncode {
28
29
/**
30
* MD5方式加密字符串
31
*
32
* @param str
33
* 要加密的字符串
34
* @return 加密后的字符串
35
* @throws NoSuchAlgorithmException
36
* @throws UnsupportedEncodingException
37
* @author yayagepei
38
* @date 2007-10-31
39
* @comment 程序的价值体现在两个方面:它现在的价值,它未来的价值
40
*/
41
public static String encoderByMd5(String str)
42
throws NoSuchAlgorithmException, UnsupportedEncodingException {
43
// 确定计算方法
44
MessageDigest md5 = MessageDigest.getInstance("MD5");
45
BASE64Encoder base64en = new BASE64Encoder();
46
// 加密后的字符串
47
String newstr = base64en.encode(md5.digest(str.getBytes("utf-8")));
48
return newstr;
49
}
50
51
/**
52
* DES加解密
53
*
54
* @param plainText
55
* 要处理的byte[]
56
* @param key
57
* 密钥
58
* @param mode
59
* 模式
60
* @return
61
* @throws InvalidKeyException
62
* @throws InvalidKeySpecException
63
* @throws NoSuchAlgorithmException
64
* @throws NoSuchPaddingException
65
* @throws BadPaddingException
66
* @throws IllegalBlockSizeException
67
* @throws UnsupportedEncodingException
68
* @author yayagepei
69
* @date 2008-10-8
70
*/
71
private static byte[] coderByDES(byte[] plainText, String key, int mode)
72
throws InvalidKeyException, InvalidKeySpecException,
73
NoSuchAlgorithmException, NoSuchPaddingException,
74
BadPaddingException, IllegalBlockSizeException,
75
UnsupportedEncodingException {
76
SecureRandom sr = new SecureRandom();
77
byte[] resultKey = makeKey(key);
78
DESKeySpec desSpec = new DESKeySpec(resultKey);
79
SecretKey secretKey = SecretKeyFactory.getInstance("DES")
80
.generateSecret(desSpec);
81
Cipher cipher = Cipher.getInstance("DES");
82
cipher.init(mode, secretKey, sr);
83
return cipher.doFinal(plainText);
84
}
85
86
/**
87
* 生产8位的key
88
*
89
* @param key
90
* 字符串形式
91
* @return
92
* @throws UnsupportedEncodingException
93
* @author yayagepei
94
* @date 2008-10-8
95
*/
96
private static byte[] makeKey(String key)
97
throws UnsupportedEncodingException {
98
byte[] keyByte = new byte[8];
99
byte[] keyResult = key.getBytes("UTF-8");
100
for (int i = 0; i < keyResult.length && i < keyByte.length; i++) {
101
keyByte[i] = keyResult[i];
102
}
103
return keyByte;
104
}
105
106
/**
107
* DES加密
108
*
109
* @param plainText
110
* 明文
111
* @param key
112
* 密钥
113
* @return
114
* @author yayagepei
115
* @date 2008-10-8
116
*/
117
public static String encoderByDES(String plainText, String key) {
118
try {
119
byte[] result = coderByDES(plainText.getBytes("UTF-8"), key,
120
Cipher.ENCRYPT_MODE);
121
return byteArr2HexStr(result);
122
} catch (Exception ex) {
123
ex.printStackTrace();
124
return "";
125
}
126
}
127
128
/**
129
* DES解密
130
*
131
* @param secretText
132
* 密文
133
* @param key
134
* 密钥
135
* @return
136
* @author yayagepei
137
* @date 2008-10-8
138
*/
139
public static String decoderByDES(String secretText, String key) {
140
try {
141
byte[] result = coderByDES(hexStr2ByteArr(secretText), key,
142
Cipher.DECRYPT_MODE);
143
return new String(result, "UTF-8");
144
} catch (Exception ex) {
145
ex.printStackTrace();
146
return "";
147
}
148
}
149
150
/**
151
* 将byte数组转换为表示16进制值的字符串, 如:byte[]{8,18}转换为:0813, 和public static byte[]
152
* hexStr2ByteArr(String strIn) 互为可逆的转换过程
153
*
154
* @param arrB
155
* 需要转换的byte数组
156
* @return 转换后的字符串
157
*/
158
private static String byteArr2HexStr(byte[] arrB){
159
int iLen = arrB.length;
160
// 每个byte用两个字符才能表示,所以字符串的长度是数组长度的两倍
161
StringBuffer sb = new StringBuffer(iLen * 2);
162
for (int i = 0; i < iLen; i++) {
163
int intTmp = arrB[i];
164
// 把负数转换为正数
165
while (intTmp < 0) {
166
intTmp = intTmp + 256;
167
}
168
// 小于0F的数需要在前面补0
169
if (intTmp < 16) {
170
sb.append("0");
171
}
172
sb.append(Integer.toString(intTmp, 16));
173
}
174
return sb.toString();
175
}
176
177
/**
178
* 将表示16进制值的字符串转换为byte数组, 和public static String byteArr2HexStr(byte[] arrB)
179
* 互为可逆的转换过程
180
*
181
* @param strIn
182
* 需要转换的字符串
183
* @return 转换后的byte数组
184
* @throws NumberFormatException
186
*/
187
private static byte[] hexStr2ByteArr(String strIn)
188
throws NumberFormatException {
189
byte[] arrB = strIn.getBytes();
190
int iLen = arrB.length;
191
// 两个字符表示一个字节,所以字节数组长度是字符串长度除以2
192
byte[] arrOut = new byte[iLen / 2];
193
for (int i = 0; i < iLen; i = i + 2) {
194
String strTmp = new String(arrB, i, 2);
195
arrOut[i / 2] = (byte) Integer.parseInt(strTmp, 16);
196
}
197
return arrOut;
198
}
199
}
200
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
179
180
181
182
183
184
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200