赞
踩
一些加积分,兑换奖品等接口,为了确保数据参数在传输过程中未经过篡改,都需要对接口数据进行加签,然后在接口服务器端对接口参数进行验签,确保两个签名是一样的,验签通过之后再进行业务逻辑处理。
双方约定好,参数按特定顺序排列,比如按首字母的顺序排列,如url:http://xxx/xxx.do?a=wersd&b=sd2354&c=4&signature=XXXXXXXXXXXX(signature为传入的签名),等你拿到入参后,将参数串a=wersd&b=sd2354&c=4按你们约定的签名规则,自己用md5加签一次,然后和入参的signature值对比,以确认调用者是否合法,这就是接口签名验证的思路。
sign=MD5(“参数1的键”+参数1的值+…+“参数N的键”+“参数N的值”+appid)
例如:url:http://127.0.0.1:5443/axfund-alipay/anxinGuess/getRanking?userId=wang&appid=165413218165&signature=sdafd45a1sda2d1a21ds3a
加密后的签名:
sign=MD5(userIdwang165413218165)
目前主要是以java 中的拦截器实现(创建一个拦截器)
package cn.com.dollar.axfund.interceptor; import cn.com.dollar.axfund.anxinguess.resp.SignResponseVo; import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; /** * @author wanglulei * @create 2019-03-27 16:47 * @desc 验签拦截器 **/ @Slf4j public class SignatureInInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception { //获取验签 String signature = request.getParameter("signature"); String resStr = JSON.toJSONString(new SignResponseVo(SignResponseVo.Code.SIGNATURE_FAIL, null)); response.setCharacterEncoding("UTF-8"); response.setContentType("application/json; charset=utf-8"); PrintWriter out = null; if (StringUtils.isBlank(signature)) { log.info("签名字段为空"); try { out = response.getWriter(); out.append(resStr); log.info(resStr); } catch (IOException e) { log.error("验签报错", e); } finally { if (out != null) { out.close(); } } } //校验 Boolean right = SignUtil.checkSign(request); if (right) { return true; } try { out = response.getWriter(); out.append(resStr); log.info(resStr); } finally { if (out != null) { out.close(); } } return false; // return true; } @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { // 在处理过程中,执行拦截 } @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { // 执行完毕,返回前拦截 } }
加密工具类
package cn.com.dollar.axfund.interceptor; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.security.GeneralSecurityException; import java.security.MessageDigest; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.TreeSet; import javax.servlet.http.HttpServletRequest; import com.alibaba.fastjson.JSONObject; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class SignUtil { private static Logger LOGGER = LoggerFactory.getLogger(SignUtil.class); private static final String secretKeyOfWxh = "YgAqeZq1eM#6#xTWkjtEGO%Ol4oxzBIlYI#k75HJml4bCr!F8YTqySDueKRY%1GB"; public static void main(String[] args) { //参数签名算法测试例子 HashMap<String, String> signMap = new HashMap<String, String>(); signMap.put("devid", "BC5549D899ED"); signMap.put("userId", "1"); signMap.put("type", "worker"); signMap.put("name", "中文测试"); System.out.println("得到签名sign1:" + getSign(signMap, secretKeyOfWxh)); } /** * 唯修汇外部接口签名验证 * * @param request * @return */ public static Boolean checkSign(HttpServletRequest request) throws IOException { Boolean flag = false; //签名 String sign = request.getParameter("signature"); Enumeration<?> pNames = request.getParameterNames(); InputStream is= null; is = request.getInputStream(); String bodyInfo = IOUtils.toString(is, "utf-8"); Map<String, String> params = new HashMap<String, String>(); JSONObject jsonObject = JSONObject.parseObject(bodyInfo); // jsonObject.forEach(); while (pNames.hasMoreElements()) { String pName = (String) pNames.nextElement(); if ("signature".equals(pName)) continue; String pValue = (String) request.getParameter(pName); params.put(pName, pValue); } if (sign.equals(getSign(params, secretKeyOfWxh))) { flag = true; } return flag; } public static String utf8Encoding(String value, String sourceCharsetName) { try { return new String(value.getBytes(sourceCharsetName), "UTF-8"); } catch (UnsupportedEncodingException e) { throw new IllegalArgumentException(e); } } private static byte[] getMD5Digest(String data) throws IOException { byte[] bytes = null; try { MessageDigest md = MessageDigest.getInstance("MD5"); bytes = md.digest(data.getBytes("UTF-8")); } catch (GeneralSecurityException gse) { throw new IOException(gse); } return bytes; } private static String byte2hex(byte[] bytes) { StringBuilder sign = new StringBuilder(); for (int i = 0; i < bytes.length; i++) { String hex = Integer.toHexString(bytes[i] & 0xFF); if (hex.length() == 1) { sign.append("0"); } sign.append(hex.toUpperCase()); //sign.append(hex.toLowerCase()); } return sign.toString(); } /** * 得到签名 * * @param params 参数集合不含secretkey * @param secret 验证接口的secretkey * @return */ public static String getSign(Map<String, String> params, String secret) { String sign = ""; StringBuilder sb = new StringBuilder(); //step1:先对请求参数排序 Set<String> keyset = params.keySet(); TreeSet<String> sortSet = new TreeSet<String>(); sortSet.addAll(keyset); Iterator<String> it = sortSet.iterator(); //step2:把参数的key value链接起来 secretkey放在最后面,得到要加密的字符串 while (it.hasNext()) { String key = it.next(); String value = params.get(key); sb.append(key).append(value); } sb.append(secret); byte[] md5Digest; try { //得到Md5加密得到sign md5Digest = getMD5Digest(sb.toString()); sign = byte2hex(md5Digest); } catch (IOException e) { LOGGER.error("生成签名错误", e); } return sign; } }
配置拦截器,使其生效(mvc-core-config.xml)
<!-- 配置拦截器 -->
<mvc:interceptors>
<!-- 配置验签拦截器 -->
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="cn.com.dollar.axfund.interceptor.SignatureInInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。