a7f828b0d32f55d8e028863fb57276362c13c76b.svn-base 4.9 KB

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