签名算法
来源:互联网 发布:城门失火 殃及池鱼知乎 编辑:程序博客网 时间:2024/06/07 05:01
【需求】
最近在公司做的微信支付和给其他系统提供接口中,都用到了签名算法,顾名思义,在接口的调用中,我们可以通过对接收的参数生成签名,从而判断传的签名与接口中通过算法得到的签名是否一致来保证数据的安全性。
【简述】
这两次接触都是通过MD5算法实现的,通用步骤一般都是:
第一步:设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
第二步:在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue
而对于加密的规则,则是我们可以自定义的。但其中也包括一些通用规则,如下:
1)参数名ASCII码从小到大排序(字典序);
2)如果参数的值为空,则不参与签名;
3)参数名区分大小写;
4)验证调用返回或接口主动通知签名时,传送的参数不参与签名,将生成的签名和该sign值作校验。
【举例】
假设传递的参数如下:
appid: wxd930ea5d5a258f4f
mch_id: 10000100
device_info: 1000
body: test
nonce_str: ibuaiVcKdpRxkhJA
第一步:对参数按照key=value的格式,并按照参数名ASCII字典序排序如下:
stringA=”appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_id=10000100&nonce_str=ibuaiVcKdpRxkhJA”;
第二步:拼接API密钥:
stringSignTemp=stringA+”&key=192006250b4c09247ec02edce69f6a2d” //注:key为商户平台设置的密钥key
sign=MD5(stringSignTemp).toUpperCase()=”9A0A8659F005D6984697E2CA0A9CF3B7” //注:MD5签名方式
【代码实现】
public class SignatureUtil { //生成签名 public static String createSign(String characterEncoding, SortedMap<String, Object> parameters, String appSecret) { StringBuffer sb = new StringBuffer(); sb.append(appSecret); Set es = parameters.entrySet(); Iterator it = es.iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); String k = (String) entry.getKey(); Object v = entry.getValue(); if (null != v && !"".equals(v) && !"sign".equals(k)) { sb.append(k + v); } } sb.append(appSecret); System.out.println(sb.toString()); String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase(); return sign; }}
自定义拦截器,实现preHandle(),除不需要拦截的请求外,都需要先进行签名校验:
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String requestUrl = request.getRequestURI(); logger.info(requestUrl); if (uncheckUrls.contains(requestUrl)) { return true; } else { //1. 获取request中所有参数集合 Enumeration<String> enu = request.getParameterNames(); //2. 将request中的参数集合排序 SortedMap<String, Object> parameterMap = new TreeMap<String, Object>(); //3. 构造参数集合 while (enu.hasMoreElements()) { String paraName = enu.nextElement(); parameterMap.put(paraName, request.getParameter(paraName)); } logger.info(parameterMap); if (parameterMap != null && !parameterMap.isEmpty()) { //4. 获取请求参数中的appKey和appSecret String appKey = request.getParameter("appKey"); String appSecret = request.getParameter("appSecret"); if (StringUtils.isBlank(appKey) || StringUtils.isBlank(appSecret)) { logger.error("appKey=" + appKey + "; appSecret=" + appSecret); logger.error("获取app_key或appSecret失败,验证签名失败!"); return false; } //5. 获取请求参数中的sign String sign = request.getParameter("sign"); if (StringUtils.isBlank(sign)) { logger.error("sign=" + sign); logger.error("获取签名失败,验证签名失败!"); return false; } //6. 将参数集合生成签名 String signResult = ""; //生成签名 signResult = SignatureUtil.createSign("UTF-8", parameterMap, appSecret); logger.info("signResult :" + signResult); //7. 验证签名是否一致 if (!StringUtils.equals(sign, signResult)) { logger.error("签名不一致,验证签名失败!"); return false; } } } return true; }
阅读全文
0 0
- 签名算法
- 签名算法
- 签名、验签算法
- URI参数签名算法
- MD5 参数签名算法
- 签名认证算法Digest
- PHP RSA2 签名算法
- APP接口签名算法
- PHP RSA2 签名算法
- OMADRM2:签名和MAC算法
- SQL 生成签名函数算法
- Android apk签名算法解析
- 速卖通接口签名算法--HMAC
- SHA2 签名算法兼容性列表
- SHA2 签名算法兼容性列表
- HMAC-SHA1签名认证算法
- 微信签名生成算法
- 微信卡券JSAPI签名校验算法
- 调用系统相机拍照功能
- Ajax核心XMLHttpRequest简析
- Java MongoDB 教程
- 【noip 2015】信息传递
- Linux针对克隆或者复制虚拟机时,更改网络(NAT模式/固定IP)适配参数
- 签名算法
- 关于Http一些基础知识的学习
- 欢迎使用CSDN-markdown编辑器
- MySQL数据类型
- 常见的版本控制管理工具
- 翻转字符串(LintCode)
- 数组重排
- 异常----异常捕捉try&catch
- macOS 安装 mysql