1 package demo;
2
3 import java.security.Key;
4 import java.security.SecureRandom;
5 import javax.crypto.Cipher;
6 import javax.crypto.SecretKey;
7 import javax.crypto.SecretKeyFactory;
8 import javax.crypto.spec.PBEKeySpec;
9 import javax.crypto.spec.PBEParameterSpec;
10 public class PasswordUtil {
11
12 /**
13 * JAVA6支持以下任意一种算法 PBEWITHMD5ANDDES PBEWITHMD5ANDTRIPLEDES
14 * PBEWITHSHAANDDESEDE PBEWITHSHA1ANDRC2_40 PBKDF2WITHHMACSHA1
15 * */
16
17 /**
18 * 定义使用的算法为:PBEWITHMD5andDES算法
19 */
20 public static final String ALGORITHM = "PBEWITHSHA1ANDRC2_40";//加密算法
21 public static final String Salt = "123456";//密钥
22
23 /**
24 * 定义迭代次数为1000次
25 */
26 private static final int ITERATIONCOUNT = 1000;
27
28 /**
29 * 获取加密算法中使用的盐值,解密中使用的盐值必须与加密中使用的相同才能完成操作. 盐长度必须为8字节
30 *
31 * @return byte[] 盐值
32 * */
33 public static byte[] getSalt() throws Exception {
34 // 实例化安全随机数
35 SecureRandom random = new SecureRandom();
36 // 产出盐
37 return random.generateSeed(8);
38 }
39
40 public static byte[] getStaticSalt() {
41 // 产出盐
42 return Salt.getBytes();
43 }
44
45 /**
46 * 根据PBE密码生成一把密钥
47 *
48 * @param password
49 * 生成密钥时所使用的密码
50 * @return Key PBE算法密钥
51 * */
52 private static Key getPBEKey(String password) {
53 // 实例化使用的算法
54 SecretKeyFactory keyFactory;
55 SecretKey secretKey = null;
56 try {
57 keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
58 // 设置PBE密钥参数
59 PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
60 // 生成密钥
61 secretKey = keyFactory.generateSecret(keySpec);
62 } catch (Exception e) {
63 // TODO Auto-generated catch block
64 e.printStackTrace();
65 }
66
67 return secretKey;
68 }
69
70 /**
71 * 加密明文字符串
72 *
73 * @param plaintext
74 * 待加密的明文字符串
75 * @param password
76 * 生成密钥时所使用的密码
77 * @param salt
78 * 盐值
79 * @return 加密后的密文字符串
80 * @throws Exception
81 */
82 public static String encrypt(String plaintext, String password, byte[] salt) {
83
84 Key key = getPBEKey(password);
85 byte[] encipheredData = null;
86 PBEParameterSpec parameterSpec = new PBEParameterSpec(salt, ITERATIONCOUNT);
87 try {
88 Cipher cipher = Cipher.getInstance(ALGORITHM);
89
90 cipher.init(Cipher.ENCRYPT_MODE, key, parameterSpec);
91
92 encipheredData = cipher.doFinal(plaintext.getBytes());
93 } catch (Exception e) {
94 }
95 return bytesToHexString(encipheredData);
96 }
97
98 /**
99 * 解密密文字符串
100 *
101 * @param ciphertext
102 * 待解密的密文字符串
103 * @param password
104 * 生成密钥时所使用的密码(如需解密,该参数需要与加密时使用的一致)
105 * @param salt
106 * 盐值(如需解密,该参数需要与加密时使用的一致)
107 * @return 解密后的明文字符串
108 * @throws Exception
109 */
110 public static String decrypt(String ciphertext, String password, byte[] salt) {
111
112 Key key = getPBEKey(password);
113 byte[] passDec = null;
114 PBEParameterSpec parameterSpec = new PBEParameterSpec(getStaticSalt(), ITERATIONCOUNT);
115 try {
116 Cipher cipher = Cipher.getInstance(ALGORITHM);
117
118 cipher.init(Cipher.DECRYPT_MODE, key, parameterSpec);
119
120 passDec = cipher.doFinal(hexStringToBytes(ciphertext));
121 }
122
123 catch (Exception e) {
124 // TODO: handle exception
125 }
126 return new String(passDec);
127 }
128
129 /**
130 * 将字节数组转换为十六进制字符串
131 *
132 * @param src
133 * 字节数组
134 * @return
135 */
136 public static String bytesToHexString(byte[] src) {
137 StringBuilder stringBuilder = new StringBuilder("");
138 if (src == null || src.length <= 0) {
139 return null;
140 }
141 for (int i = 0; i < src.length; i++) {
142 int v = src[i] & 0xFF;
143 String hv = Integer.toHexString(v);
144 if (hv.length() < 2) {
145 stringBuilder.append(0);
146 }
147 stringBuilder.append(hv);
148 }
149 return stringBuilder.toString();
150 }
151
152 /**
153 * 将十六进制字符串转换为字节数组
154 *
155 * @param hexString
156 * 十六进制字符串
157 * @return
158 */
159 public static byte[] hexStringToBytes(String hexString) {
160 if (hexString == null || hexString.equals("")) {
161 return null;
162 }
163 hexString = hexString.toUpperCase();
164 int length = hexString.length() / 2;
165 char[] hexChars = hexString.toCharArray();
166 byte[] d = new byte[length];
167 for (int i = 0; i < length; i++) {
168 int pos = i * 2;
169 d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
170 }
171 return d;
172 }
173
174 private static byte charToByte(char c) {
175 return (byte) "0123456789ABCDEF".indexOf(c);
176 }
177 //测试加密、解密
178 public static void main(String[] args) {
179 String str = "admin";
180 String password = "123456";
181 try {
182 byte[] salt = PasswordUtil.getStaticSalt();
183 String ciphertext = PasswordUtil.encrypt(str, password, salt);
184 System.out.println("密文:" + ciphertext);
185 String plaintext = PasswordUtil.decrypt(ciphertext, password, salt);
186 System.out.println("明文:" + plaintext);
187 } catch (Exception e) {
188 e.printStackTrace();
189 }
190 }
191 }