1 package cn.util;
  2 
  3 import java.io.UnsupportedEncodingException;
  4 import java.security.MessageDigest;
  5 import java.security.NoSuchAlgorithmException;
  6 import java.security.SecureRandom;
  7 
  8 import javax.crypto.Cipher;
  9 import javax.crypto.SecretKey;
 10 import javax.crypto.SecretKeyFactory;
 11 import javax.crypto.spec.DESKeySpec;
 12 
 13 /**
 14  * 加密工具类
 15  * 
 16  * md5加密出来的长度是32位
 17  * 
 18  * sha加密出来的长度是40位
 19  * 
 20  * @author 伍玉林
 21  * 
 22  */
 23 public final class EncryptUtil {
 24 
 25     private static final String PASSWORD_CRYPT_KEY = "88444488";
 26 
 27     private final static String DES = "DES";
 28 
 29     /**
 30      * 二次加密 先sha-1加密再用MD5加密
 31      * 
 32      * @param src
 33      * @return
 34      */
 35     public final static String md5AndSha(String src) {
 36         return md5(sha(src));
 37     }
 38 
 39     /**
 40      * 二次加密 先MD5加密再用sha-1加密
 41      * 
 42      * @param src
 43      * @return
 44      */
 45     public final static String shaAndMd5(String src) {
 46         return sha(md5(src));
 47     }
 48 
 49     /**
 50      * md5加密
 51      * 
 52      * @param src
 53      * @return
 54      */
 55     public final static String md5(String src) {
 56         return encrypt(src, "md5");
 57     }
 58 
 59     /**
 60      * sha-1加密
 61      * 
 62      * @param src
 63      * @return
 64      */
 65     public final static String sha(String src) {
 66         return encrypt(src, "sha-1");
 67     }
 68 
 69     /**
 70      * md5或者sha-1加密
 71      * 
 72      * @param src
 73      *            要加密的内容
 74      * @param algorithmName
 75      *            加密算法名称:md5或者sha-1,不区分大小写
 76      * @return
 77      */
 78     private final static String encrypt(String src, String algorithmName) {
 79         if (src == null || "".equals(src.trim())) {
 80             throw new IllegalArgumentException("请输入要加密的内容");
 81         }
 82         if (algorithmName == null || "".equals(algorithmName.trim())) {
 83             algorithmName = "md5";
 84         }
 85         String encryptText = null;
 86         try {
 87             MessageDigest m = MessageDigest.getInstance(algorithmName);
 88             m.update(src.getBytes("UTF8"));
 89             byte s[] = m.digest();
 90             // m.digest(src.getBytes("UTF8"));
 91             return hex(s);
 92         } catch (NoSuchAlgorithmException e) {
 93             e.printStackTrace();
 94         } catch (UnsupportedEncodingException e) {
 95             e.printStackTrace();
 96         }
 97         return encryptText;
 98     }
 99 
100     /**
101      * 密码解密
102      * 
103      * @param data
104      * @return
105      * @throws Exception
106      */
107     public final static String decrypt(String src) {
108         try {
109             return new String(decrypt(hex2byte(src.getBytes()), PASSWORD_CRYPT_KEY.getBytes()));
110         } catch (Exception e) {
111         }
112         return null;
113     }
114 
115     /**
116      * 密码加密
117      * 
118      * @param password
119      * @return
120      * @throws Exception
121      */
122     public final static String encrypt(String src) {
123         try {
124             return byte2hex(encrypt(src.getBytes(), PASSWORD_CRYPT_KEY.getBytes()));
125         } catch (Exception e) {
126         }
127         return null;
128     }
129 
130     /**
131      * 加密
132      * 
133      * @param src
134      *            数据源
135      * @param key
136      *            密钥,长度必须是8的倍数
137      * @return 返回加密后的数据
138      * @throws Exception
139      */
140     private static byte[] encrypt(byte[] src, byte[] key) throws Exception {
141         // DES算法要求有一个可信任的随机数源
142         SecureRandom sr = new SecureRandom();
143         // 从原始密匙数据创建DESKeySpec对象
144         DESKeySpec dks = new DESKeySpec(key);
145         // 创建一个密匙工厂,然后用它把DESKeySpec转换成一个SecretKey对象
146         SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
147         SecretKey securekey = keyFactory.generateSecret(dks);
148         // Cipher对象实际完成加密操作
149         Cipher cipher = Cipher.getInstance(DES);
150         // 用密匙初始化Cipher对象
151         cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);
152         // 现在,获取数据并加密正式执行加密操作
153         return cipher.doFinal(src);
154     }
155 
156     /**
157      * 解密
158      * 
159      * @param src
160      *            数据源
161      * @param key
162      *            密钥,长度必须是8的倍数
163      * @return 返回解密后的原始数据
164      * 
165      * @throws Exception
166      */
167     private final static byte[] decrypt(byte[] src, byte[] key) throws Exception {
168         // DES算法要求有一个可信任的随机数源
169         SecureRandom sr = new SecureRandom();
170         // 从原始密匙数据创建一个DESKeySpec对象
171         DESKeySpec dks = new DESKeySpec(key);
172         // 创建一个密匙工厂,然后用它把DESKeySpec对象转换成一个SecretKey对象
173         SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
174         SecretKey securekey = keyFactory.generateSecret(dks);
175         // Cipher对象实际完成解密操作
176         Cipher cipher = Cipher.getInstance(DES);
177         // 用密匙初始化Cipher对象
178         cipher.init(Cipher.DECRYPT_MODE, securekey, sr);
179         // 现在,获取数据并解密正式执行解密操作
180         return cipher.doFinal(src);
181     }
182 
183     private final static byte[] hex2byte(byte[] b) {
184         if ((b.length % 2) != 0)
185             throw new IllegalArgumentException("长度不是偶数");
186         byte[] b2 = new byte[b.length / 2];
187         for (int n = 0; n < b.length; n += 2) {
188             String item = new String(b, n, 2);
189             b2[n / 2] = (byte) Integer.parseInt(item, 16);
190         }
191         return b2;
192     }
193 
194     /**
195      * 二行制转字符串
196      * 
197      * @param b
198      * @return
199      */
200     private final static String byte2hex(byte[] b) {
201         String hs = "";
202         String stmp = "";
203         for (int n = 0; n < b.length; n++) {
204             stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
205             if (stmp.length() == 1)
206                 hs = hs + "0" + stmp;
207             else
208                 hs = hs + stmp;
209         }
210         return hs.toUpperCase();
211     }
212 
213     /**
214      * 返回十六进制字符串
215      * 
216      * @param arr
217      * @return
218      */
219     private final static String hex(byte[] arr) {
220         StringBuffer sb = new StringBuffer();
221         for (int i = 0; i < arr.length; ++i) {
222             sb.append(Integer.toHexString((arr[i] & 0xFF) | 0x100).substring(1, 3));
223         }
224         return sb.toString();
225     }
226 
227 }