如何防止请求的URL被篡改

迷南。 2021-08-01 02:07 525阅读 0赞

640?

Web项目聚集地

图文教程,技术交流

640?

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

640?wx\_fmt=png

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

640?wx\_fmt=png

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

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

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

640?wx\_fmt=png

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

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

  1. public static String generateSign(Map<String, String> parameters) {
  2. try {
  3. List<String> names = new ArrayList<>();
  4. parameters.forEach((k, v) -> {
  5. if (v != null && !Objects.equals(v, "")
  6. && !Objects.equals(k, "sign")) {
  7. names.add(k);
  8. }
  9. });
  10. List sortedNames = names.stream().sorted()
  11. .collect(Collectors.toList());
  12. StringBuffer sb = new StringBuffer();
  13. sortedNames.forEach(n ->
  14. sb.append(String.format("%s=%s", n, parameters.get(n))));
  15. String sign = md5(sb.toString());
  16. return sign;
  17. } catch (Exception e) {
  18. return "";
  19. }
  20. }
  21. private static String md5(String inputString)
  22. throws NoSuchAlgorithmException, UnsupportedEncodingException {
  23. MessageDigest md = MessageDigest.getInstance("MD5");
  24. md.update(inputString.getBytes("UTF-8"));
  25. byte[] digest = md.digest();
  26. return convertByteToHex(digest);
  27. }
  28. private static String convertByteToHex(byte[] byteData) {
  29. StringBuilder sb = new StringBuilder();
  30. for (int i = 0; i < byteData.length; i++) {
  31. sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16)
  32. .substring(1));
  33. }
  34. return sb.toString();
  35. }

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

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

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

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

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

640?wx\_fmt=png

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

推荐阅读

1.

2.

3.

欢迎您的转发和点赞

640?

▲长按关注我们

发表评论

表情:
评论列表 (有 0 条评论,525人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Web 防止恶意篡改

    要防止 Web 恶意篡改,有很多措施可以采取。 一种方法是使用 HTTPS 加密连接,这样可以保证数据在传输过程中不会被窃取或篡改。另一种方法是使用数字签名,可以确保数据来源