123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- package com.yihu.jw.utils;
- import com.alibaba.fastjson.JSONObject;
- import java.beans.BeanInfo;
- import java.beans.Introspector;
- import java.beans.PropertyDescriptor;
- import java.lang.reflect.Method;
- import java.security.MessageDigest;
- import java.security.NoSuchAlgorithmException;
- import java.util.Map;
- import java.util.TreeMap;
- /**
- * @author: wangzh
- * @date: Created in 2021/10/25 9:40
- * @description:
- * @modified By:
- * @version: 0.1
- */
- public class SignUtil {
- /**
- * description:
- * 1. 将jsonObject对象转换为键值以ascii值正序排列的treeMap集合,,
- * 以key1=value1,key2=value2密钥的形式拼接
- * 2. 以app_secret为key 0000000000000000为iv(向量) 进行aes-128-cbc加密 输出hex的密文(hex密文不要转成大写)
- * 3. 密文进行md5后就是sign值
- * create by: wangzh<br>
- * create time: 2022/3/18 10:50<br>
- * @param:
- * @return:
- */
- public static String buildAESMd5Sign(JSONObject jsonObject, String key, String iv){
- try {
- Map<String, Object> map = objectToMap(jsonObject);
- StringBuffer stringBuffer = new StringBuffer();
- for (Map.Entry<String, Object> entry : map.entrySet()){
- String k = entry.getKey();
- Object v = entry.getValue();
- //空值不传递,不参与签名组串
- if (null != v && !"".equals(v)) {
- stringBuffer.append(k).append("=").append(v).append(",");
- }
- }
- // 去掉末尾的,
- String content = stringBuffer.toString();
- content = content.substring(0, content.length() - 1);
- String signAes = AesUtil.encrypt(content, key, iv);
- return toMd5(signAes);
- } catch (Exception e) {
- e.printStackTrace();
- throw new RuntimeException(e.getMessage());
- }
- }
- /**
- * description:
- * 1. 遍历map集合,以key1=value1&key2=value2&...&key=密钥的形式拼接
- * 2. MD5加密,转换大写
- * create by: wangzh<br>
- * create time: 2021/11/4 13:45<br>
- * @param: key :
- * @return:
- */
- public static String buildSign(Map<String, Object> map, String key) {
- StringBuffer stringBuffer = new StringBuffer();
- for (Map.Entry<String, Object> entry : map.entrySet()){
- String k = entry.getKey();
- Object v = entry.getValue();
- //空值不传递,不参与签名组串
- if (null != v && !"".equals(v)) {
- stringBuffer.append(k).append("=").append(v).append("&");
- }
- }
- stringBuffer.append("key=").append(key);
- // MD5加密,结果转换为大写字符
- return toMd5(stringBuffer.toString()).toUpperCase();
- }
- /**
- * 对字符串进行MD5加密
- * @param str 需要加密的字符串
- * @return 小写MD5字符串 32位
- */
- public static String toMd5(String str) {
- String re = null;
- byte[] encrypt;
- try {
- byte[] tem = str.getBytes();
- MessageDigest md5 = MessageDigest.getInstance("md5");
- md5.reset();
- md5.update(tem);
- encrypt = md5.digest();
- StringBuilder sb = new StringBuilder();
- for (byte t : encrypt) {
- String s = Integer.toHexString(t & 0xFF);
- if (s.length() == 1) {
- s = "0" + s;
- }
- sb.append(s);
- }
- re = sb.toString();
- } catch (NoSuchAlgorithmException e) {
- e.printStackTrace();
- }
- return re;
- }
- /**
- * description:
- * 1.将对象转换为键值从小到大的treeMap集合<br>
- * create by: wangzh<br>
- * create time: 2021/10/25 10:13<br>
- * @param:
- * @return:
- */
- public static Map<String, Object> objectToMap(Object obj) throws Exception {
- if (obj == null){
- return null;
- }
- TreeMap<String, Object> map = new TreeMap<>();
- BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
- PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
- for (PropertyDescriptor property : propertyDescriptors) {
- String key = property.getName();
- if (key.compareToIgnoreCase("class") == 0) {
- continue;
- }
- Method getter = property.getReadMethod();
- Object value = getter != null ? getter.invoke(obj) : null;
- map.put(key, value);
- }
- return map;
- }
-
- /**
- * description:
- * 1. 将JSONObject对象转换为键值从小到大的treeMap集合<br>
- * 2. 若JSONObject对象里还有JSONObject对象,则递归将值按key值从小到大顺序,拼接起来
- * create by: wangzh<br>
- * create time: 2021/10/25 10:18<br>
- * @param:
- * @return:
- */
- public static Map<String, Object> objectToMap(JSONObject obj) throws Exception {
- if (obj == null){
- return null;
- }
- TreeMap<String, Object> map = new TreeMap<>();
- for (Map.Entry<String, Object> entry : obj.getInnerMap().entrySet()) {
- map.put(entry.getKey(), getJSONObjectItemJoinValue(entry.getValue()));
- }
- return map;
- }
- /**
- * description:
- * 1. 判断jsonObject对应key值的value是否是jsonObject类型<br>
- * 1.1 是,则递归获取value对象已排列属性的值,并拼接起来
- * 1.2 不是,则直接返回value的值
- * create by: wangzh<br>
- * create time: 2021/10/28 9:59<br>
- * @param:
- * @return:
- */
- private static Object getJSONObjectItemJoinValue(Object value){
- if (value instanceof JSONObject) {
- JSONObject objectItem = (JSONObject) value;
- StringBuilder itemValue = new StringBuilder();
- // 将JSONObject对象转换为键值从小到大的treeMap集合
- TreeMap<String, Object> treeMap = new TreeMap<>();
- for (Map.Entry<String, Object> entry : objectItem.entrySet()) {
- treeMap.put(entry.getKey(), entry.getValue());
- }
- // 遍历treeMap,递归获取JSONObject对象属性的值,并拼接起来
- treeMap.values().forEach(val -> itemValue.append(getJSONObjectItemJoinValue(val)));
- return itemValue.toString();
- }else{
- return value;
- }
- }
- }
|