網站首頁 編程語言 正文
?? 簽名算法
簽名生成的通用步驟如下:
- 第一步,設所有發送或者接收到的數據為集合M,將集合M內非空參數值的參數按照參數名ASCII碼從小到大排序(字典序),使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
特別注意以下重要規則:
- 參數名ASCII碼從小到大排序(字典序);
- 如果參數的值為空不參與簽名;
- 參數名區分大小寫;
- 驗證調用返回或微信主動通知簽名時,傳送的sign參數不參與簽名,將生成的簽名與該sign值作校驗。
- 微信接口可能增加字段,驗證簽名時必須支持增加的擴展字段
- 第二步,在stringA最后拼接上key得到stringSignTemp字符串,并對stringSignTemp進行MD5運算,再將得到的字符串所有字符轉換為大寫,得到sign值signValue。 注意:密鑰的長度為32個字節
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.ObjectUtils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
/**
* @author Wen先森
* @version 1.0
* @date 2022/8/25 11:07
*/
@Slf4j
public class SignatureUntils {
public static final String KEY="0de034fa56cf0ce676570d571de2705b";
/**
* 處理要簽名的數據
* 1. 獲取參數content,content為json字符串
* 2. 轉換參數成URL 鍵值對的格式(即 key1=value1&key2=value2…)
* 3. 返回整理好的待簽名數據
*/
private static String handleStr(Map<String,?> paramsMap){
//轉成map
//獲取參數名稱轉成List集合
Set<String> keySet = paramsMap.keySet();
List<String> paramNames = new ArrayList<String>(keySet);
//對參數名稱進行排序
Collections.sort(paramNames);
//把參數轉化成url鍵值對格式并返回
StringBuilder paramNameValue = new StringBuilder();
for (String paramName : paramNames ) {
if("sign".equals(paramName) || ObjectUtils.isEmpty(paramsMap.get(paramName))) {
continue;
}else{
paramNameValue.append(paramName).append("=").append(paramsMap.get(paramName)).append("&");
}
}
// paramNameValue.deleteCharAt(paramNameValue.length()-1);
return paramNameValue.toString();
}
/**
* 生成簽名;
*
* @param params
* @return
*/
static public String signForInspiry(Map<String,?> params, String key) {
//先排序
String str = handleStr(params);
StringBuffer sbkey = new StringBuffer(str);
sbkey = sbkey.append("key=" + key);
//MD5加密,結果轉換為大寫字符
String sign = toMd5(sbkey.toString()).toUpperCase();
return sign;
}
/**
* 對字符串進行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;
}
public static boolean checkSign(String sign,Map<String,?> params,String key){
try {
String signValue = signForInspiry(params, key);
if (StringUtils.endsWithIgnoreCase(signValue,sign)){
log.info("驗簽成功");
return true;
}
} catch (Exception e) {
log.info("驗簽異常");
e.printStackTrace();
}
log.info("驗簽失敗");
return false;
}
public static void main(String[] args) {
String sign="81AA2B818EAD40FE2D8E7E3242C14577";
String key="0de034fa56cf0ce676570d571de2705b";
Map<String,Object> map = new HashMap<>();
map.put("deviceSn","000SD50030180000001");
map.put("timestamp","1661759090226");
map.put("sign",sign);
map.put("orderNo","HMP2208310000584428263559179");
// 需要簽名參數
System.out.println("簽名參數:"+map);
String sortPram = handleStr(map);
// 排序后和去掉sign參數之后
System.out.println("排序后參數:"+sortPram);
String signValue = signForInspiry(map, "0de034fa56cf0ce676570d571de2705b");
// MD5加密并全部大寫
System.out.println("簽名內容:"+signValue);
// 驗簽
checkSign(sign, map, key);
}
}
原文鏈接:https://blog.csdn.net/qq_41596778/article/details/131311518
- 上一篇:沒有了
- 下一篇:沒有了
相關推薦
- 2023-07-09 Golang syncMap 詳解
- 2023-03-01 Python第三方庫undetected_chromedriver的使用_python
- 2022-10-01 C#?將?Stream?保存到文件的方法_C#教程
- 2022-08-14 Shell腳本實現監測文件變化的示例詳解_linux shell
- 2022-05-18 Python?pandas?計算每行的增長率與累計增長率_python
- 2023-01-13 C語言實現繪制貝塞爾曲線的函數_C 語言
- 2022-07-19 Linux cat more grep head tail cut uniq sort tr命令詳解
- 2022-11-16 Kotlin條件控制語句匯總講解_Android
- 欄目分類
-
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支