在以SpringBoot开发后台API接口时,会存在哪些接口不安全的因素呢?通常如何去解决的呢?本文主要介绍API接口有不安全的因素以及常见的保证接口安全的方式,重点实践如何对接口进行签名

  • SpringBoot接口 - 如何对接口进行签名

    • 准备知识点

      • API接口有哪些不安全的因素?
    • 常见的保证接口安全的方式?
      • AccessKey&SecretKey
      • 认证和授权
      • https
      • 接口签名(加密)
    • 实现案例
      • 定义注解
      • AOP拦截
      • Request封装
      • 实现接口
      • 接口测试

¶ 准备知识点

建议从接口整体的安全体系角度来理解,比如存在哪些不安全的因素,加密解密等知识点。

¶ API接口有哪些不安全的因素?

这里从体系角度,简单列举一些不安全的因素:

  • 开发者访问开放接口

    • 是不是一个合法的开发者?
  • 多客户端访问接口
    • 是不是一个合法的客户端?
  • 用户访问接口
    • 是不是一个合法的用户?
    • 有没有权限访问接口?
  • 接口传输
    • http明文传输数据?
  • 其它方面
    • 接口重放,上文介绍的接口幂等
    • 接口超时,加timestamp控制?
    • ...

¶ 常见的保证接口安全的方式?

针对上述接口存在的不安全因素,这里向你展示一些典型的保障接口安全的方式。

¶ AccessKey&SecretKey

这种设计一般用在开发接口的安全,以确保是一个合法的开发者

  • AccessKey: 开发者唯一标识
  • SecretKey: 开发者密钥

以阿里云相关产品为例

¶ 认证和授权

从两个视角去看

  • 第一: 认证和授权,认证是访问者的合法性,授权是访问者的权限分级;
  • 第二: 其中认证包括对客户端的认证以及对用户的认证
  • 对于客户端的认证

典型的是AppKey&AppSecret,或者ClientId&ClientSecret等

比如oauth2协议的client cridential模式

https://api.xxxx.com/token?grant_type=client_credentials&client_id=CLIENT_ID&client_secret=CLIENT_SECRET

grant_type参数等于client_credentials表示client credentials方式,client_id是客户端id,client_secret是客户端密钥。

返回token后,通过token访问其它接口。

  • 对于用户的认证和授权

比如oauth2协议的授权码模式(authorization code)和密码模式(resource owner password credentials)

https://api.xxxx.com/token?grant_type=password&username=USERNAME&password=PASSWORD&client_id=CLIENT_ID&scope=read

grant_type参数等于password表示密码方式,client_id是客户端id,username是用户名,password是密码。

(PS:password模式只有在授权码模式(authorization code)不可用时才会采用,这里只是举个例子而已)

可选参数scope表示申请的权限范围。(相关开发框架可以参考spring security, Apache Shiro,SA-Token (opens new window)等)

¶ https

从接口传输安全的角度,防止接口数据明文传输, 具体可以看这里

HTTP 有以下安全性问题:

  • 使用明文进行通信,内容可能会被窃听;
  • 不验证通信方的身份,通信方的身份有可能遭遇伪装;
  • 无法证明报文的完整性,报文有可能遭篡改。

HTTPs 并不是新协议,而是让 HTTP 先和 SSL(Secure Sockets Layer)通信,再由 SSL 和 TCP 通信,也就是说 HTTPs 使用了隧道进行通信。

通过使用 SSL,HTTPs 具有了加密(防窃听)、认证(防伪装)和完整性保护(防篡改)。

¶ 接口签名(加密)

接口签名(加密),主要防止请求参数被篡改。特别是安全要求比较高的接口,比如支付领域的接口。

  • 签名的主要流程

首先我们需要分配给客户端一个私钥用于URL签名加密,一般的签名算法如下:

1、首先对请求参数按key进行字母排序放入有序集合中(其它参数请参看后续补充部分);

2、对排序完的数组键值对用&进行连接,形成用于加密的参数字符串;

3、在加密的参数字符串前面或者后面加上私钥,然后用加密算法进行加密,得到sign,然后随着请求接口一起传给服务器。

例如: https://api.xxxx.com/token?key=value&timetamp=xxxx&sign=xxxx-xxx-xxx-xxxx

服务器端接收到请求后,用同样的算法获得服务器的sign,对比客户端的sign是否一致,如果一致请求有效;如果不一致返回指定的错误信息。

  • 补充:对什么签名?
  1. 主要包括请求参数,这是最主要的部分,签名的目的要防止参数被篡改,就要对可能被篡改的参数签名
  2. 同时考虑到请求参数的来源可能是请求路径path中,请求header中,请求body中。
  3. 如果对客户端分配了AppKey&AppSecret,也可加入签名计算;
  4. 考虑到其它幂等,token失效等,也会将涉及的参数一并加入签名,比如timestamp,流水号nonce等(这些参数可能来源于header)
  • 补充: 签名算法?

一般涉及这块,主要包含三点:密钥,签名算法,签名规则

  1. 密钥secret: 前后端约定的secret,这里要注意前端可能无法妥善保存好secret,比如SPA单页应用;
  2. 签名算法:也不一定要是对称加密算法,对称是反过来解析sign,这里是用同样的算法和规则计算出sign,并对比前端传过来的sign是否一致。
  3. 签名规则:比如多次加盐加密等;

PS:有读者会问,我们是可能从有些客户端获取密钥,算法和规则的(比如前端SPA单页应用生成的js中获取密钥,算法和规则),那么签名的意义在哪里?我认为签名是手段而不是目的,签名是加大攻击者攻击难度的一种手段,至少是可以抵挡大部分简单的攻击的,再加上其它防范方式(流水号,时间戳,token等)进一步提升攻击的难度而已。

  • 补充:签名和加密是不是一回事?

严格来说不是一回事:

  1. 签名是通过对参数按照指定的算法、规则计算出sign,最后前后端通过同样的算法计算出sign是否一致来防止参数篡改的,所以你可以看到参数是明文的,只是多加了一个计算出的sign。

  2. 加密是对请求的参数加密,后端进行解密;同时有些情况下,也会对返回的response进行加密,前端进行解密;这里存在加密和解密的过程,所以思路上必然是对称加密的形式+时间戳接口时效性等。

  • 补充:签名放在哪里?

签名可以放在请求参数中(path中,body中等),更为优雅的可以放在HEADER中,比如X-Sign(通常第三方的header参数以X-开头)

  • 补充:大厂开放平台是怎么做的呢?哪些可以借鉴?

以腾讯开放平台为例,请参考腾讯开放平台第三方应用签名参数sig的说明 (opens new window)

¶ 实现案例

本例子采用AOP拦截自定义注解方式实现,主要看实现的思路而已(签名的目的要防止参数被篡改,就要对可能被篡改的参数签名)。

¶ POM依赖

¶ 定义签名工具类

¶ 定义注解

¶ AOP拦截

这里可以看到需要对所有用户可能修改的参数点进行按规则签名

¶  Request封装

注册

¶  自定义异常处理类

¶  封装返回体类

¶  定义实体类

¶ 实现接口

¶ 接口测试

body参数

如果不带X-SIGN

如果X-SIGN错误

如果X-SIGN正确

SpringBoot实现接口签名防止篡改(V2)相关推荐

  1. 电商系统中API接口防止参数篡改和重放攻击(小程序/APP)

    说明:目前所有的系统架构都是采用前后端分离的系统架构,那么就不可能避免的需要服务对外提供API,那么如何保证对外的API的安全呢? 即生鲜电商中API接口防止参数篡改和重放攻击 目录 1. 什么是AP ...

  2. API 接口签名验签

    目录 一.为什么需要 API 接口签名 二.API 接口签名验签实现机制 一.为什么需要 API 接口签名 对外开放的 API 接口都会面临一些安全问题,例如伪装攻击.篡改攻击.重放攻击以及数据信息泄 ...

  3. 接口签名中的三位小伙伴signature,nonce,timestamp

    在请求一些开放平台的接口时,我们一般会在请求头中塞入一些签名相关的信息以证明身份.以微信API-V3的为例,请求头中包含的认证信息主要包含: signature(签名值) nonce(随机串) tim ...

  4. 你连对外接口签名都不会知道?有时间还是要学习学习。

    背景 周三,18:00. 小明扭了扭微微发酸的脖子,揉了揉盯着屏幕有些干涩的眼睛. 终于忙完了,临近下班,整个人心也变得放松起来. "对接方需要我们提供新的服务,下周二上线,需求我发你了,很 ...

  5. java接口 密钥签名作用_api接口签名加密请求(二)

    在"api接口签名加密请求,从springmvc4项目搭建开始"篇文章,讲述了使用java springmvc搭建api接口请求例子.为了方便php能调用,接着写了php的demo ...

  6. url 编码 与 接口签名

    Url 编码: Url编码的原则就是使用安全的字符(没有特殊用途或者特殊意义的可打印字符)去表示那些不安全的字符,以免引起歧义. 接口签名: 为了防止别人恶意刷请求,在传输 url 后面加个加密签名. ...

  7. java接口签名(Signature)实现方案续

    一.前言 由于之前写过的一片文章 (java接口签名(Signature)实现方案 )收获了很多好评,此次来说一下另一种简单粗暴的签名方案.相对于之前的签名方案,对body.paramenter.pa ...

  8. API接口签名生成算法和签名验证算法

    1.参考网上资料和书本资料,实现了API接口签名生成算法和签名验证算法. (1)参考资料:https://www.jianshu.com/p/d47da77b6419 (2)参考书籍:高级软件架构师教 ...

  9. 前端微信签名验证工具_微信JS接口签名的生成

    简要说明微信JS接口签名的生成方式 签名生成规则参与签名的字段包括有效的 jsapi_ticket(获取方式详见微信 JSSDK 文档), noncestr (随机字符串,由开发者随机生成),time ...

  10. 开放平台设计之接口签名认证

    目录 前言 签名认证 签名认证步骤: 下面以java代码举例: DEMO 前言 当前时代,数据是王 道!当我们自己的平台有了足够大的数据量,就有可能诞生一个开放平台供第三方分析.使用.那么我们怎么去实 ...

最新文章

  1. query 防止ajax重复提交
  2. 计算机组成与结 读写数据实验,计算机组成与结构实验报告现实版.doc
  3. 7种从头开始免费学习编程的方法
  4. Python—UnicodeEncodeError: 'ascii' codec can't encode/decode characters
  5. SQL2012数据库加密方法
  6. VTK:相互作用之StyleSwitch
  7. [js] 你是如何比较js函数的执行速度的?
  8. 数据集蒸馏 by Matching Training Trajectories
  9. 解题报告: LeetCode Max Points on a Line
  10. 原来你是这样的JAVA[01]-基础一瞥
  11. 中国民生银行借助Kubernetes的转型 | 凌云时刻
  12. win7护眼透明主题 “魅力win7”
  13. 使用ASP.NET Core开发Web API入门
  14. 微信公众号迁移公证书好办吗,真实经历!公众平台迁移见证需要什么材料,流程及费用详解
  15. 计算机测绘程序设计实验报告,计算机测绘程序及设计实验报告.doc
  16. html 半框添加,配眼镜全框好还是半框的好?
  17. Mac ssh locahost Connection refused
  18. 第四章 Sysrepo连接与会话
  19. python输入自己的出生年月日命运_出生年月日五行查询表 免费五行缺失查询表...
  20. 量化交易入门阶段——欧奈尔的CANSLIM模型(N 新产品、新管理层和股价创新高)

热门文章

  1. 还在为挖不到漏洞烦恼?还在为如何才能升职加薪困惑?听听徐老师怎么说.........
  2. imple introduction to LDD
  3. VBV缓冲区大小-MPEG2规范
  4. 什么是CBR,VBV,CPB
  5. Nginx学习笔记(七)——配置Nginx实现Gzip网页压缩、图片压缩
  6. 微信红包,企业付款到零钱报错:此IP地址不允许调用接口,如有需要请登录微信支付商户平台更改配置 的原因
  7. 泰灏咨询的使命及愿景
  8. 我的阿里三面,四面分享给大家
  9. Python3自然语言处理(5)——预处理
  10. 【GBT28181开发:SIP协议实践】之设备状态查询