记录一次:接口参数MD5算法校验

签名算法过程

对除签名外的所有请求参数按key做ASCII升序排列,value无需编码。

例如:一共有三个参数,a=10,b=11,c=12,那么再加上时间戳之后就是四个参数,按Key做ASCII升序排列之后,得到拼装的字符串,a10b11c1212345678,当然加不加参数名这些规则由你来定

用约定好的appkey来拼装到字符串的头部和尾部:appkey+a10b11c1212345678+appkey然后进行32位MD5加密,最后转大写。

这只是你需要接受的sign签名,除此之外,还需要接受包括在sign之中的所有参数,例如时间戳等等。

在你接受到参数之后,你同样要再次进行一遍MD5加密,然后与sign进行匹配,如果相同的话则签名正确,否则签名失败。

以下是例子:

/**
     * MD5加密工具类
     * @param src 需要加密的字符串
     * @return
     */
public class EncryptionUtil {
    public final static String MD5(String src) {
        char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        try {
            byte[] btInput = src.getBytes("UTF-8");
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            mdInst.update(btInput);
            byte[] md = mdInst.digest();
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

controller:

@RestController
@RequestMapping("/scanCode")
public class ScanCodeBuyController {

    @Autowired
    private ScanCodeBuyService scanCodeBuyService;

    /**
     * 扫码购
     * @param 'sign' 签名
     * @param 'productname' 商品名称
     * @param 'productno' 商品编号
     * @param 'timestamp' 时间戳
     * @param 'page' 当前页码
     * @param 'pageSize' 每页条数
     * @return
     */
    @PostMapping("/provideProduct")
    public ResultMsg provideProduct(@RequestBody Map<String,String> map){
        return scanCodeBuyService.provideProduct(map);
    }

}

service就不贴出来了
以下是serviceImpl:

@Service
public class ScanCodeBuyServiceImpl implements ScanCodeBuyService {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Value("${product.ScanCodeBuy.MD5Key}")
    private String MD5Key;		//MD5约定的key我放在了数据库中

    @Autowired
    private ESIndexService esIndexService;	//feign中用到的其他服务的方法

    @Override
    public ResultMsg provideProduct(Map<String, String> map) {
        //ResultMsg是我的一个数据模型DTO
        //验证签名
        ResultMsg msg = checkSign(map);
        ResultMsg esMsg = new ResultMsg();
        if (! msg.getResult()){
            return msg;
        }
        try {
            //........逻辑代码
        }catch (Exception e){
            logger.info("provideProduct======"+e);
            esMsg.setRetcode("ES");
            esMsg.setMsg("内部错误");
            esMsg.setResult(false);
            return esMsg;
        }
        return esMsg;
    }

    /**
     * 签名校验
     * @param sign
     * @return
     */
    public ResultMsg checkSign(Map<String, String> map){
        ResultMsg msg = new ResultMsg();
        if (StringUtils.isEmpty(map.get("productname"))) {
            msg.setRetcode("P1");
            msg.setMsg("productname不能为空");
            msg.setResult(false);
            return msg;
        }
        if (StringUtils.isEmpty(map.get("sign"))) {
            msg.setRetcode("S1");
            msg.setMsg("sign不能为空");
            msg.setResult(false);
            return msg;
        }
        if (StringUtils.isEmpty(map.get("productno"))) {
            msg.setRetcode("P1");
            msg.setMsg("productno不能为空");
            msg.setResult(false);
            return msg;
        }
        if (StringUtils.isEmpty(map.get("timestamp"))) {
            msg.setRetcode("T1");
            msg.setMsg("timestamp不能为空");
            msg.setResult(false);
            return msg;
        }
        if (StringUtils.isEmpty(map.get("page"))) {
            msg.setRetcode("P1");
            msg.setMsg("page不能为空");
            msg.setResult(false);
            return msg;
        }
        if (StringUtils.isEmpty(map.get("pageSize"))) {
            msg.setRetcode("P1");
            msg.setMsg("pageSize不能为空");
            msg.setResult(false);
            return msg;
        }
        String md5 = EncryptionUtil.MD5(MD5Key+map.get("page")
                +map.get("pageSize")
                +map.get("productname")
                +map.get("productno")
                +map.get("timestamp")
                +MD5Key).toUpperCase();
        logger.info("product===ScanCodeBuy==========md5本地签名"+md5);
        logger.info("product===ScanCodeBuy==========sign传入签名"+map.get("sign"));
        if (md5.equals(map.get("sign"))){
            msg.setMsg("签名匹配");
            msg.setResult(true);
            return msg;
        } else {
            msg.setRetcode("S2");
            msg.setMsg("签名不匹配");
            msg.setResult(false);
            return msg;
        }
    }

}

创作不易,点个赞吧!!

版权声明:如无特殊说明,文章均为本站原创,转载请注明出处
本文链接:https://blog.csdn.net/wsad861512140

猜你喜欢

转载自blog.csdn.net/wsad861512140/article/details/106917465
今日推荐