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 }