如何保证对外接口的安全?

这篇具有很好参考价值的文章主要介绍了如何保证对外接口的安全?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

1.什么是安全接口?
通常来说要将暴露在外网的 API 接口视为安全接口,需要实现防篡改和防重放的功能。

1.1 什么是篡改问题?
由于 HTTP 是一种无状态协议,服务端无法确定客户端发送的请求是否合法,也不了解请求中的参数是否正确。以一个充值接口为例:

http://127.0.0.1:8080/api/user/recharge?user_id=1001&amount=10

如果非法用户通过抓包获取接口参数并修改 user_id 或 amount 的值,就能为任意账户添加余额。

1.2 如何解决篡改问题?
虽然使用 HTTPS 协议能对传输的明文进行加密,但黑客仍可截获数据包进行重放攻击。两种通用解决方案是:

  1. 使用 HTTPS 加密接口数据传输,即使被黑客破解,也需要耗费大量时间和精力。
  2. 在接口后台对请求参数进行签名验证,以防止黑客篡改。

签名的实现过程如下图所示:
如何保证对外接口的安全?,SpringBoot 框架,Java 基础,java,开发语言
步骤1:客户端使用约定好的规则对传输的参数进行加密,得到签名值sign1,并且将签名值也放入请求的参数中,随请求发送至服务端。
步骤2:服务端接收到请求后,使用约定好的规则对请求的参数再次进行签名,得到签名值 sign2。
步骤3:服务端比对 sign1 和 sign2 的值,若不一致,则认定为被篡改,判定为非法请求。

1.3 什么是重放问题?
防重放也叫防复用。简单来说就是我获取到这个请求的信息之后什么也不改,,直接拿着接口的参数去重复请求这个充值的接口。此时我的请求是合法的, 因为所有参数都是跟合法请求一模一样的。重放攻击会造成两种后果:

  1. 针对插入数据库接口:重放攻击,会出现大量重复数据,甚至垃圾数据会把数据库撑爆。
  2. 针对查询的接口:黑客一般是重点攻击慢查询接口,例如一个慢查询接口1s,只要黑客发起重放攻击,就必然造成系统被拖垮,数据库查询被阻塞死。

1.4 如何解决重放问题?
防重放,业界通常基于 nonce + timestamp 方案实现。每次请求接口时生成 timestamp 和 nonce 两个额外参数,其中 timestamp 代表当前请求时间,nonce 代表仅一次有效的随机字符串。生成这两个字段后,与其他参数一起进行签名,并发送至服务端。服务端接收请求后,先比较 timestamp 是否超过规定时间(如60秒),再查看 Redis 中是否存在 nonce,最后校验签名是否一致,是否有篡改。

如何保证对外接口的安全?,SpringBoot 框架,Java 基础,java,开发语言文章来源地址https://www.toymoban.com/news/detail-837323.html

一、生成及校验Token

1.1 生成Token

public static final String equipmentSecret = "Equipment_Secret";

@PostMapping("/getToken/app")
@ApiOperation("获取鉴权token")
public Message.DataRespone<AppTokenVo> getToken(@RequestBody AppTokenRequest appTokenRequest) {
    //兼容正负3分钟
    Date endTime = DateTimeUtils.getDateAfterNow(3, "m");
    Date startTime = DateTimeUtils.getDateAfterNow(-3, "m");
    Date targetTime = new Date(appTokenRequest.getTime());
    if (startTime.after(targetTime) || targetTime.after(endTime)) {
        return Message.Time_Not_In_Use.create();
    }
    PProduct product = productService.getProductByProductKey(appTokenRequest.getProductKey());
    Map<String, String> claims = new HashMap<>();
    claims.put("productKey", appTokenRequest.getProductKey());
    claims.put("time", String.valueOf(appTokenRequest.getTime()));
    String targetSign = SignUtil.sign(claims, product.getProductSecret());
    if (!targetSign.equals(appTokenRequest.getSign())) {
        return Message.Sign_Error.create();
    }
    String token = Jwts.builder()
            .setClaims(claims)
            .setExpiration(DateTimeUtils.getDateAfterNow(2, "H"))
            //采用什么算法是可以自己选择的,不一定非要采用HS512
            .signWith(SignatureAlgorithm.HS512, equipmentSecret)
            .compact();
    AppTokenVo appTokenVo1 = new AppTokenVo();
    appTokenVo1.setToken(token);
    appTokenVo1.setExpiration(DateTimeUtils.getDateAfterNow(2, "H").getTime());
    return Message.Success.createWithData(appTokenVo1);
}

1.2 校验Token

@GetMapping("/checkToken")
@ApiOperation("校验token")
public Message.DataRespone<CheckTokenResultVo> getToken(@RequestParam(required = true, defaultValue = "") String token) {
    CheckTokenResultVo checkTokenResultVo = new CheckTokenResultVo();
    Claims claims = null;
    try {
        claims = Jwts.parser()
                .setSigningKey(equipmentSecret)
                .parseClaimsJws(token)
                .getBody();
    } catch (Exception e) {
        claims = null;
    }
    if (claims == null) {
        return Message.Token_CHECK_ERROR.create();
    }
    String productKey = String.valueOf(claims.get("productKey"));
    checkTokenResultVo.setProductKey(productKey);
    checkTokenResultVo.setExpiration(claims.getExpiration().getTime());
    return Message.Success.createWithData(checkTokenResultVo);
}

1.3 SignUtil 签名工具类

@Deprecated
public class SignUtil {
    /**
     * @param @param  sPara
     * @param @param  appecret
     * @param @return 参数描述
     * @return String    返回类型描述
     * @throws
     * @Title: buildRequestMysign
     * @Description: 签名方法
     */
    public static String sign(Map<String, String> sPara, String appecret) {
        String prestr = SignUtil.createLinkString(paraFilter(sPara)); // 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
        String mysign = "";
        mysign = MD5.sign(prestr, appecret, "utf-8");
        return mysign;
    }

    /**
     * 除去数组中的空值和签名参数
     *
     * @param sArray 签名参数组
     * @return 去掉空值与签名参数后的新签名参数组
     */
    private static Map<String, String> paraFilter(Map<String, String> sArray) {

        Map<String, String> result = new HashMap<String, String>();

        if (sArray == null || sArray.size() <= 0) {
            return result;
        }

        for (String key : sArray.keySet()) {
            String value = sArray.get(key);
            if (value == null || value.equals("") || key.equalsIgnoreCase("sign") || key.equalsIgnoreCase("sign_type")) {
                continue;
            }
            result.put(key, value);
        }

        return result;
    }

    /**
     * 把数组所有元素排序,并按照“参数=参数值”的模式用“&”字符拼接成字符串
     *
     * @param params 需要排序并参与字符拼接的参数组
     * @return 拼接后字符串
     */
    private static String createLinkString(Map<String, String> params) {

        List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);

        String prestr = "";

        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key);

            if (i == keys.size() - 1) {// 拼接时,不包括最后一个&字符
                prestr = prestr + key + "=" + value;
            } else {
                prestr = prestr + key + "=" + value + "&";
            }
        }

        return prestr;
    }
}

到了这里,关于如何保证对外接口的安全?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring Boot 如何保证接口安全?有哪些常用的接口安全技术?

    在当今互联网时代,保障接口安全已经成为了每个企业必须面对的重要问题。作为一个快速开发框架,Spring Boot 同样需要保障其接口的安全性。本文将详细介绍 Spring Boot 如何保证接口安全,以及常用的接口安全技术。 Spring Boot 作为一个快速开发框架,在开发过程中会遇到大

    2024年02月13日
    浏览(35)
  • 如何保证API接口的安全性

    API接口的安全性是非常重要的,以下是一些保证API接口安全性的措施: 用户认证、授权:接口的调用者必须提供有效的身份认证信息,包括用户名、密码、密钥等,以保证接口的调用者的身份有效性。同时,需要在接口的访问权限上进行严格控制,以确保只有经过授权的用户

    2024年02月11日
    浏览(33)
  • 如何保证接口安全,做到防篡改防重放?

    对于互联网来说,只要你系统的接口暴露在外网,就避免不了接口安全问题。如果你的接口在外网裸奔,只要让黑客知道接口的地址和参数就可以调用,那简直就是灾难。 举个例子:你的网站用户注册的时候,需要填写手机号,发送手机验证码,如果这个发送验证码的接口没

    2024年02月07日
    浏览(25)
  • 基于java框架百度AI接口车牌识别系统(springboot框架)开题答辩常规问题和如何回答

     博主介绍 :黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;专注大学生毕业设计教育和辅导。 所有项目都配有从入门到精通的基础知识视频课程,免费 项目配有对应开发文档、开题报告、任务书、

    2024年01月20日
    浏览(35)
  • API 接口应该如何设计?如何保证安全?如何签名?如何防重?

    说明:在实际的业务中,难免会跟第三方系统进行数据的交互与传递,那么如何保证数据在传输过程中的安全呢(防窃取)?除了https的协议之外,能不能加上通用的一套算法以及规范来保证传输的安全性呢? 下面我们就来讨论下常用的一些API设计的安全方法,可能不一定是

    2023年04月22日
    浏览(30)
  • 基于java框架百度AI接口植物智能识别系统 (springboot框架)开题答辩常规问题和如何回答

     博主介绍 :黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;专注大学生毕业设计教育和辅导。 所有项目都配有从入门到精通的基础知识视频课程,免费 项目配有对应开发文档、开题报告、任务书、

    2024年01月19日
    浏览(47)
  • 基于java框架百度AI接口动物智能识别系统 (springboot框架)开题答辩常规问题和如何回答

     博主介绍 :黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;专注大学生毕业设计教育和辅导。 所有项目都配有从入门到精通的基础知识视频课程,免费 项目配有对应开发文档、开题报告、任务书、

    2024年01月22日
    浏览(33)
  • 基于java框架百度AI接口果蔬智能识别系统 (springboot框架)开题答辩常规问题和如何回答

     博主介绍 :黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;专注大学生毕业设计教育和辅导。 所有项目都配有从入门到精通的基础知识视频课程,免费 项目配有对应开发文档、开题报告、任务书、

    2024年01月19日
    浏览(40)
  • 基于java框架百度AI接口人脸识别考勤签到系统 (springboot框架)开题答辩常规问题和如何回答

     博主介绍 :黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;专注大学生毕业设计教育和辅导。 所有项目都配有从入门到精通的基础知识视频课程,免费 项目配有对应开发文档、开题报告、任务书、

    2024年01月17日
    浏览(37)
  • 微服务中如何保证接口的安全性?[基于DDD和微服务的开发实战]

    大家好,我是飘渺。如果你的微服务需要向第三方开放接口,如何确保你提供的接口是安全的呢? 通常来说,要将暴露在外网的 API 接口视为安全接口,需要实现 防篡改 和 防重放 的功能。 1.1 什么是篡改问题? 由于 HTTP 是一种无状态协议,服务端无法确定客户端发送的请求

    2024年02月04日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包