|  | @ -0,0 +1,193 @@
 | 
	
		
			
				|  |  | package com.yihu.jw.security.utils;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  | import com.alibaba.fastjson.JSONObject;
 | 
	
		
			
				|  |  | import com.yihu.jw.util.http.HttpClientUtil;
 | 
	
		
			
				|  |  | import org.apache.commons.codec.digest.DigestUtils;
 | 
	
		
			
				|  |  | import org.springframework.util.StringUtils;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  | import java.util.*;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  | public class SignGenerator {
 | 
	
		
			
				|  |  |     // 调用方专属秘钥(从我方获取)
 | 
	
		
			
				|  |  |     private static final String SECRET_KEY = "hXe$2Na9hA";
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     public static void main(String[] args) {
 | 
	
		
			
				|  |  |         Map<String, Object> params3 = new HashMap<>();
 | 
	
		
			
				|  |  |         params3.put("mobile", "17602157210");
 | 
	
		
			
				|  |  |         params3.put("userName", "王志南");
 | 
	
		
			
				|  |  |         params3.put("idType", "1");
 | 
	
		
			
				|  |  |         params3.put("idNo", "350524199405230613");
 | 
	
		
			
				|  |  |         requestYkt(params3,"https://test.yanketong.com/api/ext/ykt/open/account/register");
 | 
	
		
			
				|  |  |         Map<String, Object> params1 = new HashMap<>();
 | 
	
		
			
				|  |  |         params1.put("mobile", "17602157210");
 | 
	
		
			
				|  |  |         params1.put("scene", "EXT_LOGIN");
 | 
	
		
			
				|  |  |         requestYkt(params1,"https://test.yanketong.com/api/ext/ykt/open/sms/code/send");
 | 
	
		
			
				|  |  |         Map<String, Object> params2 = new HashMap<>();
 | 
	
		
			
				|  |  |         params2.put("mobile", "17602157210");
 | 
	
		
			
				|  |  |         params2.put("code", "666666");
 | 
	
		
			
				|  |  |         String res = requestYkt(params2,"https://test.yanketong.com/api/ext/ykt/open/account/login/mobile");
 | 
	
		
			
				|  |  |         JSONObject resObj = JSONObject.parseObject(res);
 | 
	
		
			
				|  |  |         if (resObj.getString("code").equalsIgnoreCase("200")){
 | 
	
		
			
				|  |  |             JSONObject data = resObj.getJSONObject("data");
 | 
	
		
			
				|  |  |             Map<String, Object> params = new HashMap<>();
 | 
	
		
			
				|  |  |             Map<String, String> header = new HashMap<>();
 | 
	
		
			
				|  |  |             header.put("Authorization","Bearer "+data.getString("accessToken"));
 | 
	
		
			
				|  |  |             System.out.println("accessToken"+header);
 | 
	
		
			
				|  |  |             requestYktAndHeaderGet(params,header,"https://test.yanketong.com/api/ext/ykt/account/info");
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  | //
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     public static  String requestYkt(Map<String, Object> params,String url){
 | 
	
		
			
				|  |  |         params.put("timestamp", String.valueOf(System.currentTimeMillis()));
 | 
	
		
			
				|  |  |         params.put("nonce", generateNonce(16)); // 生成16位随机字符串
 | 
	
		
			
				|  |  |         // 2. 将复杂嵌套参数(含数组)展开为扁平结构
 | 
	
		
			
				|  |  |         Map<String, String> flatParams = new HashMap<>();
 | 
	
		
			
				|  |  |         flattenParams(params, "", flatParams);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         // 3. 排序参数(按ASCII码升序)
 | 
	
		
			
				|  |  |         List<String> keys = new ArrayList<>(flatParams.keySet());
 | 
	
		
			
				|  |  |         Collections.sort(keys);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         // 4. 拼接参数
 | 
	
		
			
				|  |  |         StringBuilder sb = new StringBuilder();
 | 
	
		
			
				|  |  |         for (String key : keys) {
 | 
	
		
			
				|  |  |             String value = flatParams.get(key);
 | 
	
		
			
				|  |  |             if (value != null && !"signature".equals(key)) {
 | 
	
		
			
				|  |  |                 sb.append(key).append("=").append(value).append("&");
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |         // 5. 加入秘钥
 | 
	
		
			
				|  |  |         sb.append("key=").append(SECRET_KEY);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         // 6. SHA256加密
 | 
	
		
			
				|  |  |         String signature =  DigestUtils.sha256Hex(sb.toString());
 | 
	
		
			
				|  |  |         params.put("signature",signature);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         JSONObject object = new JSONObject(params);
 | 
	
		
			
				|  |  |         System.out.println("params=="+object.toJSONString());
 | 
	
		
			
				|  |  |         String res = HttpClientUtil.sendPost(url,object.toJSONString());
 | 
	
		
			
				|  |  |         System.out.println("res="+res);
 | 
	
		
			
				|  |  |         return res;
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     public static  String requestYktAndHeader(Map<String, Object> params,Map<String, String> header,String url){
 | 
	
		
			
				|  |  |         params.put("timestamp", String.valueOf(System.currentTimeMillis()));
 | 
	
		
			
				|  |  |         params.put("nonce", generateNonce(16)); // 生成16位随机字符串
 | 
	
		
			
				|  |  |         // 2. 将复杂嵌套参数(含数组)展开为扁平结构
 | 
	
		
			
				|  |  |         Map<String, String> flatParams = new HashMap<>();
 | 
	
		
			
				|  |  |         flattenParams(params, "", flatParams);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         // 3. 排序参数(按ASCII码升序)
 | 
	
		
			
				|  |  |         List<String> keys = new ArrayList<>(flatParams.keySet());
 | 
	
		
			
				|  |  |         Collections.sort(keys);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         // 4. 拼接参数
 | 
	
		
			
				|  |  |         StringBuilder sb = new StringBuilder();
 | 
	
		
			
				|  |  |         for (String key : keys) {
 | 
	
		
			
				|  |  |             String value = flatParams.get(key);
 | 
	
		
			
				|  |  |             if (value != null && !"signature".equals(key)) {
 | 
	
		
			
				|  |  |                 sb.append(key).append("=").append(value).append("&");
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |         // 5. 加入秘钥
 | 
	
		
			
				|  |  |         sb.append("key=").append(SECRET_KEY);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         // 6. SHA256加密
 | 
	
		
			
				|  |  |         String signature =  DigestUtils.sha256Hex(sb.toString());
 | 
	
		
			
				|  |  |         params.put("signature",signature);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         JSONObject object = new JSONObject(params);
 | 
	
		
			
				|  |  |         System.out.println("params=="+object.toJSONString());
 | 
	
		
			
				|  |  |         String res = HttpClientUtil.sendPost(url,object.toJSONString(),header);
 | 
	
		
			
				|  |  |         System.out.println("res="+res);
 | 
	
		
			
				|  |  |         return res;
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     public static  String requestYktAndHeaderGet(Map<String, Object> params,Map<String, String> header,String url){
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         params.put("timestamp", String.valueOf(System.currentTimeMillis()));
 | 
	
		
			
				|  |  |         params.put("nonce", generateNonce(16)); // 生成16位随机字符串
 | 
	
		
			
				|  |  |         // 2. 将复杂嵌套参数(含数组)展开为扁平结构
 | 
	
		
			
				|  |  |         Map<String, String> flatParams = new HashMap<>();
 | 
	
		
			
				|  |  |         flattenParams(params, "", flatParams);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         // 3. 排序参数(按ASCII码升序)
 | 
	
		
			
				|  |  |         List<String> keys = new ArrayList<>(flatParams.keySet());
 | 
	
		
			
				|  |  |         Collections.sort(keys);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         // 4. 拼接参数
 | 
	
		
			
				|  |  |         StringBuilder sb = new StringBuilder();
 | 
	
		
			
				|  |  |         for (String key : keys) {
 | 
	
		
			
				|  |  |             String value = flatParams.get(key);
 | 
	
		
			
				|  |  |             if (value != null && !"signature".equals(key)) {
 | 
	
		
			
				|  |  |                 sb.append(key).append("=").append(value).append("&");
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |         // 5. 加入秘钥
 | 
	
		
			
				|  |  |         sb.append("key=").append(SECRET_KEY);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         // 6. SHA256加密
 | 
	
		
			
				|  |  |         String signature =  DigestUtils.sha256Hex(sb.toString());
 | 
	
		
			
				|  |  |         JSONObject object = new JSONObject(params);
 | 
	
		
			
				|  |  |         url +="?timestamp="+object.getString("timestamp")+"&nonce="+object.getString("nonce")+"&signature="+signature;
 | 
	
		
			
				|  |  |         System.out.println("url===="+url);
 | 
	
		
			
				|  |  |         String res = HttpClientUtil.sendGetStatic(url,header);
 | 
	
		
			
				|  |  |         System.out.println("res="+res);
 | 
	
		
			
				|  |  |         return res;
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     // 生成指定长度的随机字符串(字母+数字)
 | 
	
		
			
				|  |  |     private static String generateNonce(int length) {
 | 
	
		
			
				|  |  |         String base = "abcdefghijklmnopqrstuvwxyz0123456789";
 | 
	
		
			
				|  |  |         Random random = new Random();
 | 
	
		
			
				|  |  |         StringBuilder sb = new StringBuilder();
 | 
	
		
			
				|  |  |         for (int i = 0; i < length; i++) {
 | 
	
		
			
				|  |  |             sb.append(base.charAt(random.nextInt(base.length())));
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |         return sb.toString();
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     /**
 | 
	
		
			
				|  |  |      * 递归展开嵌套参数(支持Map和数组)
 | 
	
		
			
				|  |  |      * @param object 原始参数(可能是Map、List或基本类型)
 | 
	
		
			
				|  |  |      * @param parentKey 父级参数名
 | 
	
		
			
				|  |  |      * @param flatParams 展开后的扁平参数
 | 
	
		
			
				|  |  |      */
 | 
	
		
			
				|  |  |     @SuppressWarnings("unchecked")
 | 
	
		
			
				|  |  |     private static void flattenParams(Object object, String parentKey, Map<String, String> flatParams) {
 | 
	
		
			
				|  |  |         if (object == null) {
 | 
	
		
			
				|  |  |             return;
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |         // 处理Map类型(对象)
 | 
	
		
			
				|  |  |         if (object instanceof Map) {
 | 
	
		
			
				|  |  |             Map<String, Object> map = (Map<String, Object>) object;
 | 
	
		
			
				|  |  |             String prefix = StringUtils.hasLength(parentKey) ? parentKey + "." : "";
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             for (Map.Entry<String, Object> entry : map.entrySet()) {
 | 
	
		
			
				|  |  |                 String key = entry.getKey();
 | 
	
		
			
				|  |  |                 Object value = entry.getValue();
 | 
	
		
			
				|  |  |                 flattenParams(value, prefix + key, flatParams);
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |         // 处理List类型(数组)
 | 
	
		
			
				|  |  |         else if (object instanceof List) {
 | 
	
		
			
				|  |  |             List<Object> list = (List<Object>) object;
 | 
	
		
			
				|  |  |             String prefix = StringUtils.hasLength(parentKey) ? parentKey : "";
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             for (int i = 0; i < list.size(); i++) {
 | 
	
		
			
				|  |  |                 Object item = list.get(i);
 | 
	
		
			
				|  |  |                 // 数组元素使用索引作为键的一部分:parentKey[index]
 | 
	
		
			
				|  |  |                 flattenParams(item, prefix + "[" + i + "]", flatParams);
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |         // 处理基本类型(字符串、数字等)
 | 
	
		
			
				|  |  |         else {
 | 
	
		
			
				|  |  |             String strValue = object.toString();
 | 
	
		
			
				|  |  |             flatParams.put(parentKey, strValue);
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | }
 |