PhoneUtil.java 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. package com.fs.until;
  2. import cn.hutool.http.HttpException;
  3. import cn.hutool.http.HttpRequest;
  4. import cn.hutool.json.JSONUtil;
  5. import com.alibaba.fastjson.JSON;
  6. import com.alibaba.fastjson.JSONObject;
  7. import com.fs.common.core.domain.AjaxResult;
  8. import com.fs.common.utils.ParseUtils;
  9. import com.fs.common.utils.StringUtils;
  10. import com.fs.system.domain.SysConfig;
  11. import lombok.extern.slf4j.Slf4j;
  12. import org.springframework.stereotype.Component;
  13. import javax.crypto.Cipher;
  14. import javax.crypto.spec.SecretKeySpec;
  15. import java.util.Base64;
  16. import static com.fs.common.core.domain.AjaxResult.CODE_TAG;
  17. import static com.fs.common.core.domain.AjaxResult.DATA_TAG;
  18. @Slf4j
  19. @Component
  20. public class PhoneUtil {
  21. /**
  22. * 2025-9-3 需求替换新 key
  23. */
  24. private static String OLD_KEY = "2c8d1a7f4e9b3c6ae6d5c4b3a291f8c9";
  25. private static String USE_KEY = "AESAabCdeREssREA";
  26. //外部刷新方法
  27. public static void refreshKeyExternal(SysConfig config) {
  28. String configValue = config.getConfigValue();
  29. if (null != configValue) {
  30. JSONObject jsonObject = JSON.parseObject(configValue);
  31. if (jsonObject.containsKey("useKey") && jsonObject.containsKey("oldKey")) {
  32. USE_KEY = jsonObject.getString("useKey");
  33. OLD_KEY = jsonObject.getString("oldKey");
  34. }
  35. }
  36. }
  37. /**
  38. * 加密
  39. */
  40. public static String encryptPhone(String text) {
  41. try {
  42. String encryptedText = null;
  43. String url = "http://42.194.147.226:8000/app/common/genEncryption";
  44. // 构建请求体 JSON
  45. JSONObject jsonBody = new JSONObject();
  46. jsonBody.put("content", text);
  47. String result = HttpRequest.post(url).body(jsonBody.toString()).execute().body();
  48. //解析返回
  49. AjaxResult ajaxResult = JSONUtil.toBean(result, AjaxResult.class);
  50. //取值返回参数
  51. Object codeValue = ajaxResult.get(CODE_TAG);
  52. Object dataValue = ajaxResult.get(DATA_TAG);
  53. //判断是否成功
  54. if ("200".equals(String.valueOf(codeValue))) {
  55. encryptedText = String.valueOf(dataValue);
  56. } else {
  57. log.error("请求失败,状态码: " + codeValue);
  58. return "";
  59. }
  60. return encryptedText;
  61. } catch (HttpException e) {
  62. throw new RuntimeException(e);
  63. }
  64. }
  65. /**
  66. * 解密
  67. */
  68. public static String decryptPhone(String encryptedText) {
  69. try {
  70. String text = null;
  71. String url = "http://42.194.147.226:8000/app/common/genDecryption";
  72. // 构建请求体 JSON
  73. JSONObject jsonBody = new JSONObject();
  74. jsonBody.put("content", encryptedText);
  75. String result = HttpRequest.post(url).body(jsonBody.toString()).execute().body();
  76. //解析返回
  77. AjaxResult ajaxResult = JSONUtil.toBean(result, AjaxResult.class);
  78. //取值返回参数
  79. Object codeValue = ajaxResult.get(CODE_TAG);
  80. Object dataValue = ajaxResult.get(DATA_TAG);
  81. //判断是否成功
  82. if ("200".equals(String.valueOf(codeValue))) {
  83. text = String.valueOf(dataValue);
  84. } else {
  85. log.error("请求失败,状态码: " + codeValue);
  86. return "";
  87. }
  88. return text;
  89. } catch (HttpException e) {
  90. throw new RuntimeException(e);
  91. }
  92. }
  93. /**
  94. * 用于查询 使用老的数据加密
  95. *
  96. * @param text
  97. * @return
  98. */
  99. public static String encryptPhoneOldKey(String text) {
  100. String encryptedText = null;
  101. try {
  102. SecretKeySpec secretKey = new SecretKeySpec(OLD_KEY.getBytes(), "AES");
  103. Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
  104. // Encryption
  105. cipher.init(Cipher.ENCRYPT_MODE, secretKey);
  106. byte[] encryptedBytes = cipher.doFinal(text.getBytes());
  107. encryptedText = Base64.getEncoder().encodeToString(encryptedBytes);
  108. } catch (Exception e) {
  109. e.printStackTrace();
  110. }
  111. return encryptedText;
  112. }
  113. //
  114. public static void main(String[] args) {
  115. String text = null;
  116. String url = "http://172.16.0.114:8000/app/common/genEncryption";
  117. // 构建请求体 JSON
  118. JSONObject jsonBody = new JSONObject();
  119. jsonBody.put("content", "17749925835");
  120. String result = HttpRequest.post(url)
  121. .body(jsonBody.toString())
  122. .execute()
  123. .body();
  124. AjaxResult ajaxResult = JSONUtil.toBean(result, AjaxResult.class);
  125. System.out.println("完整响应: " + ajaxResult);
  126. Object codeValue = ajaxResult.get(CODE_TAG);
  127. Object dataValue = ajaxResult.get(DATA_TAG);
  128. System.out.println("code原始值: '" + codeValue + "'");
  129. System.out.println("data原始值: '" + dataValue + "'");
  130. // 使用 String.valueOf 确保类型安全
  131. if ("200".equals(String.valueOf(codeValue))) {
  132. text = String.valueOf(dataValue);
  133. System.out.println("加密结果: " + text);
  134. } else {
  135. System.out.println("请求失败,状态码: " + codeValue);
  136. }
  137. }
  138. /**
  139. * 解密加*
  140. */
  141. public static String decryptPhoneMk(String encryptedText) {
  142. String text = null;
  143. try {
  144. text = decryptPhone(encryptedText);
  145. text = text.replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2");
  146. } catch (Exception e) {
  147. log.warn("decryptPhoneMk 解密失败 text: {}, msg: {}", encryptedText, e.getMessage(), e);
  148. text = encryptedText;
  149. }
  150. return text;
  151. }
  152. public static String decryptAutoPhoneMk(String encryptedText) {
  153. String text = null;
  154. if (encryptedText != null && encryptedText != "") {
  155. if (encryptedText.length() > 11) {
  156. try {
  157. text = decryptPhone(encryptedText);
  158. text = text.replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2");
  159. } catch (Exception e) {
  160. log.warn("decryptAutoPhoneMk 解密失败 text: {}, msg: {}", encryptedText, e.getMessage(), e);
  161. text = encryptedText;
  162. }
  163. } else {
  164. text = ParseUtils.parsePhone(encryptedText);
  165. }
  166. }
  167. return text;
  168. }
  169. /**
  170. * 手机号加密 *
  171. *
  172. * @param text 手机号
  173. * @return 加密后手机号
  174. */
  175. public static String hiddenPhone(String text) {
  176. if (StringUtils.isBlank(text)) {
  177. return text;
  178. }
  179. return "***********";
  180. }
  181. /**
  182. * 显示前3位
  183. *
  184. * @param text 手机号
  185. * @return 加密后手机号
  186. */
  187. public static String displayPre3Phone(String text) {
  188. if (StringUtils.isBlank(text)) {
  189. return text;
  190. }
  191. text = text.trim();
  192. if (text.length() > 11) {
  193. text = decryptPhone(text);
  194. }
  195. return text.replaceAll("(\\d{3})\\d*", "$1********");
  196. }
  197. /**
  198. * 判断文本中是否存在手机号
  199. *
  200. * @param text 原始文本
  201. * @return 是否存在手机号
  202. */
  203. private static boolean containsPhoneNumber(String text) {
  204. if (text == null || text.trim().isEmpty()) {
  205. return false;
  206. }
  207. // 手机号正则
  208. String phoneRegex = "1[3-9]\\d{9}";
  209. java.util.regex.Pattern pattern = java.util.regex.Pattern.compile(phoneRegex);
  210. java.util.regex.Matcher matcher = pattern.matcher(text);
  211. return matcher.find();
  212. }
  213. private static final String PUBLIC_KEY_STR = "ylrz112233";
  214. /**
  215. * XOR 加密(返回 Base64)(对于解析后的电话明文加密,适用于前端解密)
  216. *
  217. * @param data 明文电话
  218. * @return String 密文
  219. */
  220. public static String xorEncrypt(String data) {
  221. byte[] dataBytes = data.getBytes(java.nio.charset.StandardCharsets.UTF_8);
  222. byte[] keyBytes = PUBLIC_KEY_STR.getBytes(java.nio.charset.StandardCharsets.UTF_8);
  223. byte[] result = new byte[dataBytes.length];
  224. for (int i = 0; i < dataBytes.length; i++) {
  225. result[i] = (byte) (dataBytes[i] ^ keyBytes[i % keyBytes.length]);
  226. }
  227. return Base64.getEncoder().encodeToString(result);
  228. }
  229. /**
  230. * XOR 解密
  231. *
  232. * @param base64Str Base64 编码的密文
  233. * @param privateKey 私钥字符串(如 "ylrz987654321")
  234. * @return 解密后的明文字符串
  235. */
  236. public static String xorDecrypt(String base64Str, String privateKey) {
  237. // 1. Base64 解码为字节数组
  238. byte[] encryptedBytes = Base64.getDecoder().decode(base64Str);
  239. // 2. 私钥字符串转字节数组(UTF-8 编码)
  240. byte[] keyBytes = privateKey.getBytes(java.nio.charset.StandardCharsets.UTF_8);
  241. // 3. 逐字节异或
  242. byte[] resultBytes = new byte[encryptedBytes.length];
  243. for (int i = 0; i < encryptedBytes.length; i++) {
  244. resultBytes[i] = (byte) (encryptedBytes[i] ^ keyBytes[i % keyBytes.length]);
  245. }
  246. // 4. 将字节数组按 UTF-8 解码为字符串
  247. return new String(resultBytes, java.nio.charset.StandardCharsets.UTF_8);
  248. }
  249. }