SignUtil.java 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. package com.yihu.jw.utils;
  2. import com.alibaba.fastjson.JSONObject;
  3. import java.beans.BeanInfo;
  4. import java.beans.Introspector;
  5. import java.beans.PropertyDescriptor;
  6. import java.lang.reflect.Method;
  7. import java.security.MessageDigest;
  8. import java.security.NoSuchAlgorithmException;
  9. import java.util.Map;
  10. import java.util.TreeMap;
  11. /**
  12. * @author: wangzh
  13. * @date: Created in 2021/10/25 9:40
  14. * @description:
  15. * @modified By:
  16. * @version: 0.1
  17. */
  18. public class SignUtil {
  19. /**
  20. * description:
  21. * 1. 将jsonObject对象转换为键值以ascii值正序排列的treeMap集合,,
  22. * 以key1=value1,key2=value2密钥的形式拼接
  23. * 2. 以app_secret为key 0000000000000000为iv(向量) 进行aes-128-cbc加密 输出hex的密文(hex密文不要转成大写)
  24. * 3. 密文进行md5后就是sign值
  25. * create by: wangzh<br>
  26. * create time: 2022/3/18 10:50<br>
  27. * @param:
  28. * @return:
  29. */
  30. public static String buildAESMd5Sign(JSONObject jsonObject, String key, String iv){
  31. try {
  32. Map<String, Object> map = objectToMap(jsonObject);
  33. StringBuffer stringBuffer = new StringBuffer();
  34. for (Map.Entry<String, Object> entry : map.entrySet()){
  35. String k = entry.getKey();
  36. Object v = entry.getValue();
  37. //空值不传递,不参与签名组串
  38. if (null != v && !"".equals(v)) {
  39. stringBuffer.append(k).append("=").append(v).append(",");
  40. }
  41. }
  42. // 去掉末尾的,
  43. String content = stringBuffer.toString();
  44. content = content.substring(0, content.length() - 1);
  45. String signAes = AesUtil.encrypt(content, key, iv);
  46. return toMd5(signAes);
  47. } catch (Exception e) {
  48. e.printStackTrace();
  49. throw new RuntimeException(e.getMessage());
  50. }
  51. }
  52. /**
  53. * description:
  54. * 1. 遍历map集合,以key1=value1&key2=value2&...&key=密钥的形式拼接
  55. * 2. MD5加密,转换大写
  56. * create by: wangzh<br>
  57. * create time: 2021/11/4 13:45<br>
  58. * @param: key :
  59. * @return:
  60. */
  61. public static String buildSign(Map<String, Object> map, String key) {
  62. StringBuffer stringBuffer = new StringBuffer();
  63. for (Map.Entry<String, Object> entry : map.entrySet()){
  64. String k = entry.getKey();
  65. Object v = entry.getValue();
  66. //空值不传递,不参与签名组串
  67. if (null != v && !"".equals(v)) {
  68. stringBuffer.append(k).append("=").append(v).append("&");
  69. }
  70. }
  71. stringBuffer.append("key=").append(key);
  72. // MD5加密,结果转换为大写字符
  73. return toMd5(stringBuffer.toString()).toUpperCase();
  74. }
  75. /**
  76. * 对字符串进行MD5加密
  77. * @param str 需要加密的字符串
  78. * @return 小写MD5字符串 32位
  79. */
  80. public static String toMd5(String str) {
  81. String re = null;
  82. byte[] encrypt;
  83. try {
  84. byte[] tem = str.getBytes();
  85. MessageDigest md5 = MessageDigest.getInstance("md5");
  86. md5.reset();
  87. md5.update(tem);
  88. encrypt = md5.digest();
  89. StringBuilder sb = new StringBuilder();
  90. for (byte t : encrypt) {
  91. String s = Integer.toHexString(t & 0xFF);
  92. if (s.length() == 1) {
  93. s = "0" + s;
  94. }
  95. sb.append(s);
  96. }
  97. re = sb.toString();
  98. } catch (NoSuchAlgorithmException e) {
  99. e.printStackTrace();
  100. }
  101. return re;
  102. }
  103. /**
  104. * description:
  105. * 1.将对象转换为键值从小到大的treeMap集合<br>
  106. * create by: wangzh<br>
  107. * create time: 2021/10/25 10:13<br>
  108. * @param:
  109. * @return:
  110. */
  111. public static Map<String, Object> objectToMap(Object obj) throws Exception {
  112. if (obj == null){
  113. return null;
  114. }
  115. TreeMap<String, Object> map = new TreeMap<>();
  116. BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
  117. PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
  118. for (PropertyDescriptor property : propertyDescriptors) {
  119. String key = property.getName();
  120. if (key.compareToIgnoreCase("class") == 0) {
  121. continue;
  122. }
  123. Method getter = property.getReadMethod();
  124. Object value = getter != null ? getter.invoke(obj) : null;
  125. map.put(key, value);
  126. }
  127. return map;
  128. }
  129. /**
  130. * description:
  131. * 1. 将JSONObject对象转换为键值从小到大的treeMap集合<br>
  132. * 2. 若JSONObject对象里还有JSONObject对象,则递归将值按key值从小到大顺序,拼接起来
  133. * create by: wangzh<br>
  134. * create time: 2021/10/25 10:18<br>
  135. * @param:
  136. * @return:
  137. */
  138. public static Map<String, Object> objectToMap(JSONObject obj) throws Exception {
  139. if (obj == null){
  140. return null;
  141. }
  142. TreeMap<String, Object> map = new TreeMap<>();
  143. for (Map.Entry<String, Object> entry : obj.getInnerMap().entrySet()) {
  144. map.put(entry.getKey(), getJSONObjectItemJoinValue(entry.getValue()));
  145. }
  146. return map;
  147. }
  148. /**
  149. * description:
  150. * 1. 判断jsonObject对应key值的value是否是jsonObject类型<br>
  151. * 1.1 是,则递归获取value对象已排列属性的值,并拼接起来
  152. * 1.2 不是,则直接返回value的值
  153. * create by: wangzh<br>
  154. * create time: 2021/10/28 9:59<br>
  155. * @param:
  156. * @return:
  157. */
  158. private static Object getJSONObjectItemJoinValue(Object value){
  159. if (value instanceof JSONObject) {
  160. JSONObject objectItem = (JSONObject) value;
  161. StringBuilder itemValue = new StringBuilder();
  162. // 将JSONObject对象转换为键值从小到大的treeMap集合
  163. TreeMap<String, Object> treeMap = new TreeMap<>();
  164. for (Map.Entry<String, Object> entry : objectItem.entrySet()) {
  165. treeMap.put(entry.getKey(), entry.getValue());
  166. }
  167. // 遍历treeMap,递归获取JSONObject对象属性的值,并拼接起来
  168. treeMap.values().forEach(val -> itemValue.append(getJSONObjectItemJoinValue(val)));
  169. return itemValue.toString();
  170. }else{
  171. return value;
  172. }
  173. }
  174. }