MD5加密算法的Java实现

  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 }
原文地址:https://www.cnblogs.com/wanying521/p/5179397.html