sign签名工具类 (ascii 排序、encode 参数编码、MD5加密)


public class SignUtils {

/**
* 获取key的方法
* @param inMap
* @param keys
* @return
*/
private static StringBuffer getKeys(Map<String, String> inMap,List<String> keys){

StringBuffer sb = new StringBuffer();
for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
if (!key.equals("sign") && !StringUtils.isEmpty(key)) {
String value = inMap.get(key);
if (value.equals("")|| null == value ) {
continue;
}
sb.append(key);
sb.append("=");
sb.append(value);
sb.append("&");
}
}
return sb;
}

/**
* ascii 值升序排列
* @param map
* @return
*/
public static Map<String, String> sortByKey(Map<String, String> map,String ve){
//创建一个带有比较器的TreeMap
Map<String, String> treeMap = new TreeMap<>(String::compareTo);
//是否需要对参数进行编码
if ( ve != null && ve.equals("1")) {
for (Map.Entry<String,String> entry : map.entrySet()) {
String key = urlEncode(entry.getKey());
treeMap.put(key,entry.getValue());
}
} else {
//将你的map传入treeMap
treeMap.putAll(map);
}
return treeMap;
}

/**
* 获取sign 签名
* @param inMap
* @param secretKey
* @return
*/
public static String getSign(Map<String, String> inMap, String secretKey) {
List<String> keys = new ArrayList<String>(inMap.keySet());
Collections.sort(keys);
StringBuffer sb = null;
sb = getKeys(inMap,keys);
sb.append("requestKey").append("=").append(secretKey);
String sign = MD5.MD5Encode(sb.toString(), CharsetUtils.utf);
return sign;
}

/**
* 是否需要对参数进行编码
* @param source
* @return
*/
public static String urlEncode(String source) {
return UriUtils.encode(source, StandardCharsets.UTF_8);
}


public static void main(String[] args) {


// System.out.println(urlEncode("傻瓜蛋bbbbsadghthas"));

Map<String,String> map = new HashMap<>();
map.put("digaln", "1");
map.put("adgdge", "hello");
map.put("fgfg", "abc");
map.put("啥", "455456");
map.put("zff", "72");
map.put("sgfsge", "4242");
map.put("bgsof", "424");
System.out.println("排序前:" + map);
Map<String, String> s = sortByKey(map,"2");
// String sign = getSign(s,"dgoigjoihagooaeag");
System.out.println("排序后:" + s );

}

}



@Component
public class SignInterceptor implements HandlerInterceptor {

private static final Logger log = LoggerFactory.getLogger("SignInterceptor");

@Autowired
private RedisTemplate redisTemplate;
@Autowired
private ISysApiUserService iSysApiUserService;

/**
*
* @param request:请求对象
* @param response:响应对象
* @param handler:处理对象:controller中的信息
* @return:true表示正常,false表示被拦截
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

//依次检查传入值是否存在
String appId = request.getHeader("appId");
if (StringUtils.isBlank(appId)) {
ServletUtil.renderString(response, JSON.toJSONString(ResponseData.buildOk("appId 参数未传入")));
return false;
}
String comId = request.getHeader("comId");
if (StringUtils.isBlank(comId)) {
ServletUtil.renderString(response, JSON.toJSONString(ResponseData.buildOk("comId 参数未传入")));
return false;
}
String sign = request.getHeader("sign");
if (StringUtils.isBlank(sign)) {
ServletUtil.renderString(response, JSON.toJSONString(ResponseData.buildOk("sign 签名未传入")));
return false;
}
// 查询缓存中的值
StringBuffer redisKey = new StringBuffer(RedisConstants.REDIS_KEY_API_USER).append(":").append(appId).append(comId);
log.info("//缓存key值:" + redisKey);
SysApiUser sysApiUser = (SysApiUser) redisTemplate.opsForValue().get(redisKey);
if (null == sysApiUser) {
// 获取传进的对象
Map<String, String> signMap = request.getTrailerFields();
// 获取ve参数
String ve = signMap.get("ve");
// 移除map中空的value值
removeNullValue(signMap);
// 数据库中查询私钥
SysApiUser oldApiUser = iSysApiUserService.getOne(new QueryWrapper<SysApiUser>().lambda().eq(SysApiUser::getAppId,appId).eq(SysApiUser::getComId,comId));
if ( null != oldApiUser) {
// 针对传进的map排序
Map<String,String> signEncryptMap = sortByKey(signMap,ve);
// 获取签名
String signEncrypt = getSign(signEncryptMap,oldApiUser.getSecretKey());
log.info("signEncrypt 添加至缓存:"+ signEncrypt);
redisTemplate.opsForValue().set("sign",signEncrypt);
//后端MD5签名校验与前端签名sign值比对
if ( !signEncrypt.equals(sign)) {
ServletUtil.renderString(response, JSON.toJSONString(ResponseData.buildOk("签名失败,请核实")));
return false;
}
} else {
throw new Exception("数据库表中未配置相关用户的私钥");
}
} else {
// 获取缓存中的私钥
String secretKey = sysApiUser.getSecretKey();
if ( !secretKey.equals(sign)) {
ServletUtil.renderString(response, JSON.toJSONString(ResponseData.buildOk("缓存中的签名失败,请核实")));
return false;
}
}
return true;
}

    
/**
* 获取body信息
*
* @param request
* @return
*/
private String getBody(HttpServletRequest request) {
InputStream is = null;
StringBuilder sb = new StringBuilder();
try {
is = request.getInputStream();
byte[] b = new byte[4096];
for (int n; (n = is.read(b)) != -1; ) {
sb.append(new String(b, 0, n));
}
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}

    


}


posted @ 2020-08-09 11:04  猿码哥  阅读(875)  评论(0编辑  收藏  举报