专栏首页Web项目聚集地如何防止请求的URL被篡改

如何防止请求的URL被篡改

Web项目聚集地

图文教程,技术交流

如图,是我们模拟的一个从浏览器发送给服务器端的转账请求。久一的ID是 web_resource,正在操作100元的转账。

再如图,因为是通过浏览器 `url` 访问服务,这个时候金额被篡改成了 200,那么服务器接受到了200,直接扣除了200怎么解决?这就是本文要讲解的内容。

防止url被篡改的方式有很多种,本文就讲述最简单的一种,通过 secret 加密验证。

道理很简单,服务器接收到了 price 和 id,如果有办法校验一下他们是否被修改过不就就可以了吗?

那么我们传递的时候增加一个参数,叫做sign,sign是使用用户不可见的一个secret和price、id组合加密获得,然后传递给服务器端。当服务器端接收到请求的时候,获取到price、id,通过同样的secret加密和sign比较如果相同就通过校验,不同则被篡改过。

那么问题来了,如果参数特别多怎么办?

所以通用的做法是,把所有需要防止篡改的参数按照字母正序排序,然后顺序拼接到一起,再和secret组合加密得到 sign。具体的做法可以参照如下。

  public static String generateSign(Map<String, String> parameters) {
    try {
        List<String> names = new ArrayList<>();
        parameters.forEach((k, v) -> {
            if (v != null && !Objects.equals(v, "") 
                && !Objects.equals(k, "sign")) {
                names.add(k);
            }
        });

        List sortedNames = names.stream().sorted()
            .collect(Collectors.toList());
        StringBuffer sb = new StringBuffer();
        sortedNames.forEach(n -> 
            sb.append(String.format("%s=%s", n, parameters.get(n))));
        String sign = md5(sb.toString());
        return sign;
    } catch (Exception e) {
        return "";
    }
  }

  private static String md5(String inputString)
       throws NoSuchAlgorithmException, UnsupportedEncodingException {

    MessageDigest md = MessageDigest.getInstance("MD5");
    md.update(inputString.getBytes("UTF-8"));

    byte[] digest = md.digest();

    return convertByteToHex(digest);
  }

  private static String convertByteToHex(byte[] byteData) {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < byteData.length; i++) {
        sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16)
        .substring(1));
    }
    return sb.toString();
  }

generateSign 就是所有需要加密的参数,包括secret

有的同学担心,那么他万一猜到了我的加密算法怎么办,这个不用担心,你的secret是保持在服务器端的,不会暴漏出去的,所以他知道了算法也不会知道具体加密的内容。

那么问题又来了,如果小明通过抓包工具获取到了URL,他是不是可以无限制的访问这个地址呢?那就出现了“久一”的钱被一百一百的转空了。

那可怎么办?这里涉及到了另一个话题,接口的幂等,我们后面会详细讲解怎么通过幂等控制重复扣款。这里我们要讲解的是怎么控制 URL 失效。

这里又有一个通用的做法,就是再添加一个参数 timestamp。对的,就是当前的时间戳。服务器获取到 timestamp 以后检验一下是否在5分钟以内,如果不是直接返回请求失效就可以了?那么如果timestamp 被篡改了呢?不会的,因为我们按照上面的做法同样对 timestamp 做了加密防止篡改。

最简单的校验接口被篡改的方式,你学会了吗?

本文分享自微信公众号 - Web项目聚集地(web_resource)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-10-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 我珍藏的神兵利器(软件篇)

    快速启动应用+文件搜索+各种实用插件(计算器、翻译、网页快速访问等)。我的最爱,没有它我几乎半残。

    用户1093975
  • Linux养成计划(七)

    导读: 此文章介绍Linux常用指令中的运行级别,以及我们忘记root密码时的解决方案。毕竟实际开发中我们用的都是命令行,所以掌握常用的指令对于Linux系统使...

    用户1093975
  • Linux养成计划(四)

    Linux系统会内建 vi 文本编辑器,Vim具有程序编程的能力,可以看作是Vi的增强版本,可以主动的以字体颜色辨别语法的正确性,方便程序设计、补充代码、编译及...

    用户1093975
  • Linux常用命令06 - ps

    在 Linux 中,程序的运行实例称为进程。 有时候,在 Linux 机器上工作时,您可能需要了解当前正在运行的进程。

    叉叉敌
  • 易观于揚:数据分析是人工智能的基础构件

    ? 整理 | 明明、谷磊 2018年1月16日,全球最大中文 IT 社区 CSDN 在北京举办了“ AI 生态赋能2018论坛暨 CSDN AI 新战略发布会...

    小莹莹
  • 易观于揚:数据分析是人工智能的基础构件

    整理 | 明明、谷磊 2018年1月16日,全球最大中文 IT 社区 CSDN 在北京举办了“ AI 生态赋能2018论坛暨 CSDN AI 新战略发布会”。在...

    AI科技大本营
  • JAVA版孔乙己

    听人家背地里谈论,孔乙己原来也是计算机硕士,但终究是因为打撸啊撸时间太长,忘了新生代和老年代的区别,去IT类培训学校做了一名学生

    哲洛不闹
  • torch.cuda.is_available

    torch.cuda.get_device_name(0) 返回gpu名字,设备索引默认从0开始;

    sofu456
  • Spring boot+VUE+websocket 实现消息推送

            最近涉及消息通知功能,在管理员创建发送消息时,登陆用户可以实时接收到新增消息的提醒,避免频繁刷新,通过websocket取代轮询setInter...

    用户1409099
  • 万字长文 | 线性代数的本质课程笔记完整合集!

    线性代数中最基础,最根源的组成部分是向量,那么什么是向量呢?从不同学生的视角看,有以下三种观点:

    zenRRan

扫码关注云+社区

领取腾讯云代金券