在日常设计及开发中,为确保数据传输和数据存储的安全,可通过特定的算法,将数据明文加密成复杂的密文。目前主流加密手段大致可分为单向加密和双向加密。
单向加密:通过对数据进行摘要计算生成密文,密文不可逆推还原。算法代表:Base64,MD5,SHA;
双向加密:与单向加密相反,可以把密文逆推还原成明文,双向加密又分为对称加密和非对称加密。
对称加密:指数据使用者必须拥有相同的密钥才可以进行加密解密,就像彼此约定的一串暗号。算法代表:DES,3DES,AES,IDEA,RC4,RC5;
非对称加密:相对对称加密而言,无需拥有同一组密钥,非对称加密是一种“信息公开的密钥交换协议”。非对称加密需要公开密钥和私有密钥两组密钥,公开密钥和私有密钥是配对起来的,也就是说使用公开密钥进行数据加密,只有对应的私有密钥才能解密。这两个密钥是数学相关,用某用户密钥加密后的密文,只能使用该用户的加密密钥才能解密。如果知道了其中一个,并不能计算出另外一个。因此如果公开了一对密钥中的一个,并不会危害到另外一个密钥性质。这里把公开的密钥为公钥,不公开的密钥为私钥。算法代表:RSA,DSA。
======================================================
3DES算法
3DES是三重数据加密,且可以逆推的一种算法方案。但由于3DES的算法是公开的,所以算法本身没有密钥可言,主要依靠唯一密钥来确保数据加解密的安全。到目前为止,仍没有人能破解3DES。
3DES(或称为Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称。它相当于是对每个数据块应用三次DES加密算法。由于计算机运算能力的增强,原版DES密码的密钥长度变得容易被暴力破解;3DES即是设计用来提供一种相对简单的方法,即通过增加DES的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。
3DES加解密工具类
1 package tqx.demo;
2
3
4
5 import java.net.URLDecoder;
6 import java.net.URLEncoder;
7 import java.security.Key;
8
9 import javax.crypto.Cipher;
10 import javax.crypto.SecretKeyFactory;
11 import javax.crypto.spec.DESedeKeySpec;
12 import javax.crypto.spec.IvParameterSpec;
13
14 import com.alibaba.fastjson.JSONObject;
15
16 /**
17 * 3DES加密工具类
18 *
19 */
20 public class INITDES3Util {
21 // 密钥
22 private static String SECRETKEY = "INbSvyvOTkSkcRNSc8HpHIat";
23 // 向量
24 private static String IV = "drS66rwt";
25 // 加解密统一使用的编码方式
26 private final static String encoding = "utf-8";
27
28 public INITDES3Util(String s,String v ){
29 this.SECRETKEY=s;
30 this.IV=v;
31 }
32
33 /**
34 * 3DES加密
35 *
36 * @param plainText
37 * 普通文本
38 * @return
39 */
40 public String encrypt(String plainText) throws Exception {
41 Key deskey = null;
42 DESedeKeySpec spec = new DESedeKeySpec(SECRETKEY.getBytes());
43 SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
44 deskey = keyfactory.generateSecret(spec);
45
46 Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
47 IvParameterSpec ips = new IvParameterSpec(IV.getBytes());
48 cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
49 byte[] encryptData = cipher.doFinal(plainText.getBytes(encoding));
50 return Base64.encode(encryptData);
51 }
52
53 /**
54 * 3DES解密
55 *
56 * @param encryptText
57 * 加密文本
58 * @return
59 */
60 public String decrypt(String encryptText) throws Exception {
61 Key deskey = null;
62 DESedeKeySpec spec = new DESedeKeySpec(SECRETKEY.getBytes());
63 SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
64 deskey = keyfactory.generateSecret(spec);
65 Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
66 IvParameterSpec ips = new IvParameterSpec(IV.getBytes());
67 cipher.init(Cipher.DECRYPT_MODE, deskey, ips);
68
69 byte[] decryptData = cipher.doFinal(Base64.decode(encryptText));
70
71 return new String(decryptData, encoding);
72 }
73
74 /**
75 * 3DES加密
76 *
77 * @param secretKey
78 * 秘钥
79 * @param iv
80 * 偏移向量
81 * @param plainText
82 * 普通文本
83 * @return
84 * @throws Exception
85 */
86 public static String encryptString(String secretKey, String iv,
87 String plainText) throws Exception {
88 Key deskey = null;
89 DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());
90 SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
91 deskey = keyfactory.generateSecret(spec);
92
93 Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
94 IvParameterSpec ips = new IvParameterSpec(iv.getBytes());
95 cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
96 byte[] encryptData = cipher.doFinal(plainText.getBytes(encoding));
97 return Base64.encode(encryptData);
98 }
99
100 /**
101 * 3DES解密
102 *
103 * @param secretKey
104 * 秘钥
105 * @param iv
106 * 偏移向量
107 * @param encryptText
108 * 密文
109 * @return
110 * @throws Exception
111 */
112 public static String decryptString(String secretKey, String iv,
113 String encryptText) throws Exception {
114 Key deskey = null;
115 DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());
116 SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
117 deskey = keyfactory.generateSecret(spec);
118 Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
119 IvParameterSpec ips = new IvParameterSpec(iv.getBytes());
120 cipher.init(Cipher.DECRYPT_MODE, deskey, ips);
121
122 byte[] decryptData = cipher.doFinal(Base64.decode(encryptText));
123
124 return new String(decryptData, encoding);
125 }
126
127 /**
128 * 3DES解码后解密
129 *
130 * @param secretKey
131 * 秘钥
132 * @param iv
133 * 偏移向量
134 * @param encryptText
135 * 密文
136 * @return
137 * @throws Exception
138 */
139 public static String decryptStringURLDecoder(String secretKey, String iv,
140 String encryptText) throws Exception {
141 String retJsonStr = decryptString(secretKey, iv,
142 URLDecoder.decode(encryptText));
143 return retJsonStr;
144 }
145
146 /**
147 * URLEncoder编码加密信息
148 *
149 * @param secretKey
150 * @param iv
151 * @param plainText
152 * @return
153 * @throws Exception
154 */
155 public static String encryptStringURLEncoder(String secretKey, String iv,
156 String plainText) throws Exception {
157 String base64Str = encryptString(secretKey, iv, plainText);
158 return URLEncoder.encode(base64Str);
159 }
160
161
162 public static void main(String[] args) throws Exception {
163 String result="";
164 INITDES3Util desSource=new INITDES3Util("INbSvyvOTkSkcRNSc8HpHIat","drS66rwt");
165 //JSONObject outData = new JSONObject();
166 //JSONObject resultOutData = new JSONObject();
167 String outputStr="123456";
168 String para=desSource.encrypt(outputStr);//加密json串
169 System.out.println(para);
170 String decryptString = INITDES3Util.encryptString("INbSvyvOTkSkcRNSc8HpHIat","drS66rwt", "sysadmin");
171 System.out.println(decryptString);
172
173 }
174
175 }
URLDecoder类包含一个decode(String s,String charcter)静态方法,它可以将看上去乱码的特殊字符串转换成普通字符串
URLEncoder类包含一个encode(String s,String charcter)静态方法,它可以将普通字符串转换成application/x-www-form-urlencoded MIME字符串
base64
1 package tqx.demo;
2
3
4 import java.io.ByteArrayOutputStream;
5 import java.io.IOException;
6 import java.io.OutputStream;
7
8 /**
9 * Base64编码工具类
10 *
11 */
12 public class Base64 {
13 private static final char[] legalChars =
14
15 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
16 .toCharArray();
17
18 public static String encode(byte[] data) {
19 int start = 0;
20 int len = data.length;
21 StringBuffer buf = new StringBuffer(data.length * 3 /
22
23 2);
24
25 int end = len - 3;
26 int i = start;
27 int n = 0;
28
29 while (i <= end) {
30 int d = ((((int) data[i]) & 0x0ff) << 16)
31 | ((((int) data[i + 1]) & 0x0ff)
32
33 << 8)
34 | (((int) data[i + 2]) & 0x0ff);
35
36 buf.append(legalChars[(d >> 18) & 63]);
37 buf.append(legalChars[(d >> 12) & 63]);
38 buf.append(legalChars[(d >> 6) & 63]);
39 buf.append(legalChars[d & 63]);
40
41 i += 3;
42
43 if (n++ >= 14) {
44 n = 0;
45 buf.append(" ");
46 }
47 }
48
49 if (i == start + len - 2) {
50 int d = ((((int) data[i]) & 0x0ff) << 16)
51 | ((((int) data[i + 1]) & 255)
52
53 << 8);
54
55 buf.append(legalChars[(d >> 18) & 63]);
56 buf.append(legalChars[(d >> 12) & 63]);
57 buf.append(legalChars[(d >> 6) & 63]);
58 buf.append("=");
59 } else if (i == start + len - 1) {
60 int d = (((int) data[i]) & 0x0ff) << 16;
61
62 buf.append(legalChars[(d >> 18) & 63]);
63 buf.append(legalChars[(d >> 12) & 63]);
64 buf.append("==");
65 }
66
67 return buf.toString();
68 }
69
70 private static int decode(char c) {
71 if (c >= 'A' && c <= 'Z')
72 return ((int) c) - 65;
73 else if (c >= 'a' && c <= 'z')
74 return ((int) c) - 97 + 26;
75 else if (c >= '0' && c <= '9')
76 return ((int) c) - 48 + 26 + 26;
77 else
78 switch (c) {
79 case '+':
80 return 62;
81 case '/':
82 return 63;
83 case '=':
84 return 0;
85 default:
86 throw new RuntimeException("unexpectedcode: " + c);
87 }
88 }
89
90 /**
91 * Decodes the given Base64 encoded String to a new byte array.
92
93 The byte
94 * array holding the decoded data is returned.
95 */
96
97 public static byte[] decode(String s) {
98
99 ByteArrayOutputStream bos = new ByteArrayOutputStream();
100 try {
101 decode(s, bos);
102 } catch (IOException e) {
103 throw new RuntimeException();
104 }
105 byte[] decodedBytes = bos.toByteArray();
106 try {
107 bos.close();
108 bos = null;
109 } catch (IOException ex) {
110 System.err.println("Error while decoding BASE64:" + ex.toString());
111 }
112 return decodedBytes;
113 }
114
115 private static void decode(String s, OutputStream os) throws
116
117 IOException {
118 int i = 0;
119
120 int len = s.length();
121
122 while (true) {
123 while (i < len && s.charAt(i) <= ' ')
124 i++;
125
126 if (i == len)
127 break;
128
129 int tri = (decode(s.charAt(i)) << 18)
130 + (decode(s.charAt(i + 1)) <<
131
132 12)
133 + (decode(s.charAt(i + 2)) << 6)
134 + (decode(s.charAt(i + 3)));
135
136 os.write((tri >> 16) & 255);
137 if (s.charAt(i + 2) == '=')
138 break;
139 os.write((tri >> 8) & 255);
140 if (s.charAt(i + 3) == '=')
141 break;
142 os.write(tri & 255);
143
144 i += 4;
145 }
146 }
147 }
测试
package tqx.demo;
public class Demo3 {
public static void main(String[] args) throws Exception {
String encryptStringURLEncoder = INITDES3Util.encryptStringURLEncoder("INbSvyvOTkSkcRNSc8HpHIat", "drS66rwt", "123456");
System.out.println("电话加密后:"+encryptStringURLEncoder);
String decryptStringURLDecoder = INITDES3Util.decryptStringURLDecoder("INbSvyvOTkSkcRNSc8HpHIat", "drS66rwt", encryptStringURLEncoder);
System.out.println("电话解密后:"+decryptStringURLDecoder);
String encryptStringURLEncoder1 = INITDES3Util.encryptStringURLEncoder("INbSvyvOTkSkcRNSc8HpHIat", "drS66rwt", "tqx");
System.out.println("24加密后:"+encryptStringURLEncoder1);
String decryptStringURLDecoder1 = INITDES3Util.decryptStringURLDecoder("INbSvyvOTkSkcRNSc8HpHIat", "drS66rwt", encryptStringURLEncoder1);
System.out.println("24解密后:"+decryptStringURLDecoder1);
String encryptStringURLEncoder2 = INITDES3Util.encryptStringURLEncoder("INbSvyvOTkSkcRNSc8HpHIat", "drS66rwt", "512501197203035172");
System.out.println("身份证号加密后:"+encryptStringURLEncoder2);
String decryptStringURLDecoder2 = INITDES3Util.decryptStringURLDecoder("INbSvyvOTkSkcRNSc8HpHIat", "drS66rwt", encryptStringURLEncoder2);
System.out.println("身份证号解密后:"+decryptStringURLDecoder2);
byte[] decode = Base64.decode("12345600");
System.out.println(decode.toString());
}
}
针对特殊字符的处理 '+'
str.toString()).replaceAll("\\+", "%2B");
// 密钥24位
private static String SECRETKEY = "INbSvyvOTkSkcRNSc8HpHIat";
// 向量6位
private static String IV = "drS66rwt";
生成方法
package tqx.demo;
import java.util.Random;
public class RandomUtil {
public static final String ALLCHAR = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static final String LETTERCHAR = "abcdefghijkllmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static final String NUMBERCHAR = "0123456789";
/**
* 返回一个定长的带因子的固定的随机字符串(只包含大小写字母、数字)
*
* @param length
* 随机字符串长度
* @return 随机字符串
*/
public static String generateStringByKey(int length, int channel) {
StringBuffer sb = new StringBuffer();
Random random = new Random(channel);
for (int i = 0; i < length; i++) {
sb.append(ALLCHAR.charAt(random.nextInt(ALLCHAR.length())));
}
return sb.toString();
}
/**
* 返回一个定长的随机字符串(只包含大小写字母、数字)
*
* @param length
* 随机字符串长度
* @return 随机字符串
*/
public static String generateString(int length) {
StringBuffer sb = new StringBuffer();
Random random = new Random();
for (int i = 0; i < length; i++) {
sb.append(ALLCHAR.charAt(random.nextInt(ALLCHAR.length())));
}
return sb.toString();
}
/**
* 返回一个定长的随机纯字母字符串(只包含大小写字母)
*
* @param length
* 随机字符串长度
* @return 随机字符串
*/
public static String generateMixString(int length) {
StringBuffer sb = new StringBuffer();
Random random = new Random();
for (int i = 0; i < length; i++) {
sb.append(ALLCHAR.charAt(random.nextInt(LETTERCHAR.length())));
}
return sb.toString();
}
/**
* 返回一个定长的随机纯大写字母字符串(只包含大小写字母)
*
* @param length
* 随机字符串长度
* @return 随机字符串
*/
public static String generateLowerString(int length) {
return generateMixString(length).toLowerCase();
}
/**
* 返回一个定长的随机纯小写字母字符串(只包含大小写字母)
*
* @param length
* 随机字符串长度
* @return 随机字符串
*/
public static String generateUpperString(int length) {
return generateMixString(length).toUpperCase();
}
/**
* 生成一个定长的纯0字符串
*
* @param length
* 字符串长度
* @return 纯0字符串
*/
public static String generateZeroString(int length) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < length; i++) {
sb.append('0');
}
return sb.toString();
}
/**
* 根据数字生成一个定长的字符串,长度不够前面补0
*
* @param num
* 数字
* @param fixdlenth
* 字符串长度
* @return 定长的字符串
*/
public static String toFixdLengthString(long num, int fixdlenth) {
StringBuffer sb = new StringBuffer();
String strNum = String.valueOf(num);
if (fixdlenth - strNum.length() >= 0) {
sb.append(generateZeroString(fixdlenth - strNum.length()));
} else {
throw new RuntimeException("将数字" + num + "转化为长度为" + fixdlenth + "的字符串发生异常!");
}
sb.append(strNum);
return sb.toString();
}
/**
* 每次生成的len位数都不相同
*
* @param param
* @return 定长的数字
*/
public static int getNotSimple(int[] param, int len) {
Random rand = new Random();
for (int i = param.length; i > 1; i--) {
int index = rand.nextInt(i);
int tmp = param[index];
param[index] = param[i - 1];
param[i - 1] = tmp;
}
int result = 0;
for (int i = 0; i < len; i++) {
result = result * 10 + param[i];
}
return result;
}
public static void main(String[] args) {
int channel = 555555;// 测试因子比生产因子少1
System.out.println("返回一个定长的带因子的固定的随机字符串(只包含大小写字母、数字):" + generateStringByKey(24, channel));
System.out.println("返回一个定长的随机字符串(只包含大小写字母、数字):" + generateString(24));
System.out.println("返回一个定长的随机纯字母字符串(只包含大小写字母):" + generateMixString(6));
System.out.println("返回一个定长的随机纯大写字母字符串(只包含大小写字母):" + generateLowerString(6));
System.out.println("返回一个定长的随机纯小写字母字符串(只包含大小写字母):" + generateUpperString(6));
System.out.println("生成一个定长的纯0字符串:" + generateZeroString(6));
System.out.println("根据数字生成一个定长的字符串,长度不够前面补0:" + toFixdLengthString(123, 6));
int[] in = { 1, 2, 3, 4, 5, 6, 7 };
System.out.println("每次生成的len位数都不相同:" + getNotSimple(in, 3));
}
}
返回一个定长的带因子的固定的随机字符串(只包含大小写字母、数字):MaigTil28hVETWTssFHGtYDx
返回一个定长的随机字符串(只包含大小写字母、数字):6sBcIpRocWTyBLiKvyNAQ0Sd
返回一个定长的随机纯字母字符串(只包含大小写字母):LLQMLv
返回一个定长的随机纯大写字母字符串(只包含大小写字母):mp6d7s
返回一个定长的随机纯小写字母字符串(只包含大小写字母):MWYWIF
生成一个定长的纯0字符串:000000
根据数字生成一个定长的字符串,长度不够前面补0:000123
每次生成的len位数都不相同:651