sign签名的实现

最近工作中,在开发app端接口的时候,app端调用后端服务接口的时候,一直报签名错误。这里介绍一下前后端生成签名的大概流程。
  所以需要明白的几点:
        1、前后端签名我们项目采用的md5的加密方法。 具体方法可以看下面代码。当然还可以有其他的好多的加密方法。这只是其中一种。
        2、前端和后端将数据生成对应的sign必须采用相同的规则,生成对应的字符串,然后进行md5加密,这样生成的sign才能相同。如果数据被拦截,修改其中任意一点数据,都会造成前后端数据不一致,从而导致生成的sign不一致。
        3、一般小的项目验证签名在后端会添加到一个拦截器里面。只要app端调用都会进行拦截验证。正常的大项目,肯定一般会在网关层进行拦截验证。
  以下是我模拟的我们一个生成sign的验证流程,希望对你有帮助,代码走起。

public class Test {
    public static void main(String[] args) {
        //map 前台传过来的参数,其中sign是前台数据经过md5加密之后,生成的sign标识
        Map<String,String> map = new HashMap<>();
        map.put("name","hxx");
        map.put("age","20");
        map.put("sex","");
        map.put("email","xxx@qq.com");
        map.put("sign","7876850823c9c0d3c2c411a9693b36ff");
        //后台需要根据前台传过来的参数(map),生成新的签名,此时必须排除前台生成的sign参数
        List<String> exludeKey = new ArrayList<>();
        exludeKey.add("sign");
        // 为了增加安全性,前后台可以增加一个密钥,前后端在加密的时候将此密钥增加到md5加密里面(此密钥可以配置到共享配置中心,后面可以随时变化)
        String bindKey = "bindKey";
        String secretKey = "123456qwerty";
        //生成新的签名
        String signResult = sign(map,secretKey,bindKey,exludeKey);
        if(signResult.equals(map.get("sign"))){
           System.out.println(true);
        }else{
            System.out.println(false);
        }

    }

    /**
     * MD5加密字符串
     * @param str
     * @return
     */
    public static String encryptToMD5(String str) {
        System.out.println("md5加密前数据...."+str);
        String result = DigestUtils.md5DigestAsHex(str.getBytes(StandardCharsets.UTF_8));
        System.out.println("md5加密后数据...."+result);
        return result;
    }

    /**
     * 生成新的签名
     * @param map   前端传过来的参数
     * @param bindKey    前端和后端共同增加约定key
     * @param secretKey  前端和后端共同增加约定value(共享配置中心可以随时变化)
     * @param exludeKey  排除前端传过来的sign签名字段
     * @return
     */
    public static String sign(Map<String,String> map,String bindKey,String secretKey,List<String> exludeKey){
        List<String> sortList = new ArrayList();
        // 前台穿过的参数,过滤空、null、sign。获取对应的key,并且对key进行排序(排序的目的是为了前端和后端保持相同的规则,然后生成相同字符串,这样生成的sign才能相同)
        for(Map.Entry entry: map.entrySet()){
            String value = entry.getValue() + "";
            if(null != value && !"".equals(value)&& !exludeKey.contains(entry.getKey())){
                sortList.add((String) entry.getKey());
            }
        }
        //对key进行排序
        Collections.sort(sortList);
        StringBuffer sb = new StringBuffer();
        for(int i = 0;i < sortList.size();i++){
            String key = sortList.get(i);
            sb.append(key).append("=").append(map.get(key)).append("&");
        }
        sb.append(bindKey).append("=").append(secretKey);
        //最终获取到的需要加密的字符串
        System.out.println("排序后的字符串:" + sb.toString());
        return Test.encryptToMD5(sb.toString());
    }
}

 下面图片展示我们服务端具体的代码实现

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值