package cc.mrbird.febs.pay.util; import cc.mrbird.febs.common.exception.JPException; import cc.mrbird.febs.pay.model.Request; import cc.mrbird.febs.pay.model.Response; import cc.mrbird.febs.pay.model.SignTypeEnum; import cn.hutool.core.util.ObjectUtil; import com.alipay.service.schema.util.StringUtil; import java.lang.reflect.Field; import java.util.*; /** * 签名、验签的工具类 * @author chenyf * @date 2018-12-15 */ public class SignUtil { public final static String SIGN_SEPARATOR = "&";//分隔符 public final static String SIGN_EQUAL = "=";//等于号 public final static String SIGN_KEY_PARAM_NAME = "key"; public final static List NOT_SIGN_PARAM = Arrays.asList(new String[]{"sign","aesKey","aes_key","sec_key"});//不参与签名/验签的参数 /** * 验证签名 * @param response * @param key * @return */ public static boolean verify(Response response, String key) throws Exception { String signStr = getSortedString(response); if(SignTypeEnum.MD5.getValue().equals(response.getSign_type())){ signStr = HEXUtil.encode(genMD5Sign(signStr, key), true); if(signStr.equals(response.getSign())){ return true; }else{ return false; } }else if(SignTypeEnum.RSA.getValue().equals(response.getSign_type())){ return RSAUtil.verify(signStr, key, HEXUtil.decode(response.getSign()), true); }else{ return false; } } /** * 生成签名 * @param request * @param key * @return */ public static void sign(Request request, String key) throws Exception { if(ObjectUtil.isEmpty(request)){ return; }else if(StringUtil.isEmpty(request.getMch_id()) || StringUtil.isEmpty(request.getSign_type())){ request.setSign(""); return; } if(StringUtil.isEmpty(request.getRand_str())){ request.setRand_str(RandomUtil.get32LenStr()); } String signStr = getSortedString(request); if(SignTypeEnum.MD5.getValue().equals(request.getSign_type())){ signStr = HEXUtil.encode(genMD5Sign(signStr, key), true); }else if(SignTypeEnum.RSA.getValue().equals(request.getSign_type())){ signStr = HEXUtil.encode(RSAUtil.sign(signStr, key, true)); }else{ //抛出签名失败的异常 throw new JPException("签名失败,未预期的签名类型:"+request.getSign_type()); } request.setSign(signStr); } protected static String getSortedString(Object obj) throws Exception { Field[] fields = obj.getClass().getDeclaredFields(); Map map = new HashMap(); for(int i=0; i keys = new ArrayList(map.keySet()); Collections.sort(keys); // 排序map for (int i = 0; i < keys.size(); i++) { String key = keys.get(i); String value = map.get(key); if(i != 0){ content.append(SIGN_SEPARATOR); } content.append(key).append(SIGN_EQUAL).append(value); } return content.toString(); } private static byte[] genMD5Sign(String signStr, String key){ return MD5Util.getMD5(signStr + SIGN_SEPARATOR + SIGN_KEY_PARAM_NAME + SIGN_EQUAL + key); } }