3des/cbc/pkcs/5padding加密解密

加解密的工具类SecurityDESUtil:

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
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.security.Security;


* 解密工具类
* 将AppKey转换为byte[]
* 将Token转换为向量IV
* 使用3des解密,运算模式CBC,填充模式PKCS7。获得解密后是byte[],使用utf8编码格式转换为字符串
*/
public final class {
private static final String SECRET_KEY = "DESede";
//3des解密,运算模式CBC,填充模式PKCS7
private static final String CIPHER = "DESede/CBC/PKCS5Padding";
private static final Charset CHARSET = Charset.forName("UTF-8");
private static Cipher cipher = null;
private static SecretKey key = null;

static {
try {
synchronized(SecurityDESUtil.class){
cipher = Cipher.getInstance(CIPHER);
}

} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}

}

private static byte[] getAppKey(String appKey) {
final byte[] appKeys = parseHexStr2Byte(appKey);
final byte[] tmpkey ={ 0, 1, 2, 3, 4, 5, 6, 7, 2, 3, 0, 1, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7 };
for (int ii = 0; ii < tmpkey.length; ii++)
{
tmpkey[ii] = appKeys[ii];
}
return tmpkey;
}


* 加密
* @param iv
* @param content
* @return
*/
public synchronized static String encrypt(String appKey, String iv, String content){
try {
byte[] tmpKey = getAppKey(appKey);
key = new SecretKeySpec(tmpKey, SECRET_KEY);
final byte[] tmpiv = getIv(iv);
final byte[] contentBytes = content.getBytes(CHARSET);
final IvParameterSpec ivParameterSpec = new IvParameterSpec(tmpiv);
cipher.init(Cipher.ENCRYPT_MODE, key, ivParameterSpec);
final byte[] bytes = cipher.doFinal(contentBytes);
return Base64.encodeBase64String(bytes);
}catch (Exception e){
e.printStackTrace();
return null;
}
}

private static byte[] getIv(String iv) {
final byte[] byteIv = parseHexStr2Byte(iv);
byte[] tmpiv ={ 0, 1, 2, 3, 4, 5, 6, 7 };
for (int i = 0; i < tmpiv.length; i++)
{
tmpiv[i] = byteIv[i];
}
return tmpiv;
}


* 解密
* @param iv
* @param content
* @return
*/
public synchronized static String decrypt(String appKey, String iv, String content){
try {
byte[] tmpKey = getAppKey(appKey);
key = new SecretKeySpec(tmpKey, SECRET_KEY);
final byte[] byteIv = getIv(iv);
final IvParameterSpec ivParameterSpec = new IvParameterSpec(byteIv);
// CBC requires an initialization vector
cipher.init(Cipher.DECRYPT_MODE, key, ivParameterSpec);
final byte[] decoderStr = Base64.decodeBase64(content);
final byte[] bytes = cipher.doFinal(decoderStr,0,decoderStr.length);
return new String(bytes,CHARSET);
} catch (Exception e) {
e.printStackTrace();
return null;
}

}


* 将二进制转换成16进制
* @param buf
* @return String
*/
public synchronized static String parseByte2HexStr(byte buf[]) {
StringBuffer sb = new StringBuffer();
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 byte[]
*/
public synchronized 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;
}
}