Springboot之接口简单加密和验证


简书地址

设计方案

跟第三方系统打交道时一般会双方协商一组秘钥,然后将接口的参数进行约定的处理,防止接口被盗刷。

通用参数,在header上加入两个参数,参数信息如下:
| 参数名称 | 参数位置 |字段说明| 是否必须|
| —- | —- |—- |—- |
| sign | header |签名,将appid、secret、当前日期三个参数md处理 | 是|
| timestamp | header | 时间戳,到秒 | 是 |

签名字段sign说明:
将[appid | secret | 当前日期]进行md5加密取32位小写算法,比如:
appId: 12345
secret:123
当前日期:20201001
则sign=MD5(12345|123|20201001)=faa2626dbd47f0548d9622b1a748d672

要求

同一组参数只在10s内有效,考虑到服务器和客户端时间差,前后5秒有效。

备份代码

入口函数

    public Boolean demo(HttpServletRequest request) {
        String cubaSign = request.getHeader("sign");
        String cubaTimestamp = request.getHeader("timestamp");
        log.info("请求参数sign为【{}】,时间参数为【{}】", cubaSign, cubaTimestamp);
        if (!isValidTimestamp(Long.valueOf(cubaTimestamp))) {
            log.error("调用接口连接超时,请求时间戳为【{}】", cubaTimestamp);
            return false;
        }
        if (!isValidSign(cubaSign)) {
            log.error("调用接口sign校验不通过");
            return false;
        }
        return true;
    }

俩个验证函数

import org.apache.commons.codec.digest.DigestUtils;
import java.time.LocalDateTime;
import java.time.ZoneOffset;

    /**
     * 校验sign
     * 将[appid | secret | 当前日期]进行md5加密。
     */
    private Boolean isValidSign(String cubaSign) {
        String sign = appId + "|" + secret + "|" + DateUtil.date2str(new Date(), DateUtil.DAY_FORMAT);
        String md5Sign = DigestUtils.md5Hex(sign).toUpperCase();
        log.info("校验sign是否正确,md5机密后的sign【{}】", md5Sign);
        return md5Sign.equals(cubaSign);
    }

    /**
     * 校验时间戳
     * 当前时间正负5秒之内的时间的时间戳
     */
    private Boolean isValidTimestamp(Long cubaTimestamp) {
        LocalDateTime localDateTime = LocalDateTime.now();
        Long after5Time = localDateTime.plusSeconds(30).toEpochSecond(ZoneOffset.ofHours(8));
        Long before5Time = localDateTime.plusSeconds(-30).toEpochSecond(ZoneOffset.ofHours(8));
        return (before5Time < cubaTimestamp) && (cubaTimestamp < after5Time);
    &#125;

评论
  目录