如何设计一个安全的对外接口?

转载
https://blog.csdn.net/weixin_46742102/article/details/108831868?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-108831868-blog-125359890.235%5Ev38%5Epc_relevant_anti_t3_base&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-108831868-blog-125359890.235%5Ev38%5Epc_relevant_anti_t3_base&utm_relevant_index=2

前言
最近有个项目需要对外提供一个接口,提供公网域名进行访问,而且接口和交易订单有关,所以安全性很重要;这里整理了一下常用的一些安全措施以及具体如何去实现。

安全措施
个人觉得安全措施大体来看主要在两个方面,一方面就是如何保证数据在传输过程中的安全性,另一个方面是数据已经到达服务器端,服务器端如何识别数据,如何不被攻击;下面具体看看都有哪些安全措施。

1.数据加密
我们知道数据在传输过程中是很容易被抓包的,如果直接传输比如通过http协议,那么用户传输的数据可以被任何人获取;所以必须对数据加密,常见的做法对关键字段加密比如用户密码直接通过md5加密;现在主流的做法是使用https协议,在http和tcp之间添加一层加密层(SSL层),这一层负责数据的加密和解密;

2.数据加签
数据加签就是由发送者产生一段无法伪造的一段数字串,来保证数据在传输过程中不被篡改;你可能会问数据如果已经通过https加密了,还有必要进行加签吗?数据在传输过程中经过加密,理论上就算被抓包,也无法对数据进行篡改;但是我们要知道加密的部分其实只是在外网,现在很多服务在内网中都需要经过很多服务跳转,所以这里的加签可以防止内网中数据被篡改;

3.时间戳机制
数据是很容易被抓包的,但是经过如上的加密,加签处理,就算拿到数据也不能看到真实的数据;但是有不法者不关心真实的数据,而是直接拿到抓取的数据包进行恶意请求;这时候可以使用时间戳机制,在每次请求中加入当前的时间,服务器端会拿到当前时间和消息中的时间相减,看看是否在一个固定的时间范围内比如5分钟内;这样恶意请求的数据包是无法更改里面时间的,所以5分钟后就视为非法请求了;

4.AppId机制
大部分网站基本都需要用户名和密码才能登录,并不是谁来能使用我的网站,这其实也是一种安全机制;对应的对外提供的接口其实也需要这么一种机制,并不是谁都可以调用,需要使用接口的用户需要在后台开通appid,提供给用户相关的密钥;在调用的接口中需要提供appid+密钥,服务器端会进行相关的验证;

5.限流机制
本来就是真实的用户,并且开通了appid,但是出现频繁调用接口的情况;这种情况需要给相关appid限流处理,常用的限流算法有令牌桶和漏桶算法;

6.黑名单机制
如果此appid进行过很多非法操作,或者说专门有一个中黑系统,经过分析之后直接将此appid列入黑名单,所有请求直接返回错误码;

7.数据合法性校验
这个可以说是每个系统都会有的处理机制,只有在数据是合法的情况下才会进行数据处理;每个系统都有自己的验证规则,当然也可能有一些常规性的规则,比如身份证长度和组成,电话号码长度和组成等等;

如何实现
以上大体介绍了一下常用的一些接口安全措施,当然可能还有其他我不知道的方式,希望大家补充,下面看看以上这些方法措施,具体如何实现;

1.数据加密
现在主流的加密方式有对称加密和非对称加密; 对称加密:对称密钥在加密和解密的过程中使用的密钥是相同的,常见的对称加密算法有DES,AES;优点是计算速度快,缺点是在数据传送前,发送方和接收方必须商定好秘钥,然后使双方都能保存好秘钥,如果一方的秘钥被泄露,那么加密信息也就不安全了;

非对称加密:服务端会生成一对密钥,私钥存放在服务器端,公钥可以发布给任何人使用;优点就是比起对称加密更加安全,但是加解密的速度比对称加密慢太多了;广泛使用的是RSA算法;

两种方式各有优缺点,而https的实现方式正好是结合了两种加密方式,整合了双方的优点,在安全和性能方面都比较好;

对称加密和非对称加密代码实现,jdk提供了相关的工具类可以直接使用,此处不过多介绍; 关于https如何配置使用相对来说复杂一些,可以参考本人的之前的文章HTTPS分析与实战

2.数据加签
数据签名使用比较多的是md5算法,将需要提交的数据通过某种方式组合和一个字符串,然后通过md5生成一段加密字符串,这段加密字符串就是数据包的签名,可以看一个简单的例子:

str:参数1={参数1}&参数2={参数2}&……&参数n={参数n}$key={用户密钥};
MD5.encrypt(str);
注意最后的用户密钥,客户端和服务端都有一份,这样会更加安全;

3.时间戳机制
解密后的数据,经过签名认证后,我们拿到数据包中的客户端时间戳字段,然后用服务器当前时间去减客户端时间,看结果是否在一个区间内,伪代码如下:

long interval=5601000;//超时时间
long clientTime=request.getparameter(“clientTime”);
long serverTime=System.currentTimeMillis();
if(serverTime-clientTime>interval){
return new Response(“超过处理时长”)
}
4.AppId机制
生成一个唯一的AppId即可,密钥使用字母、数字等特殊字符随机生成即可;生成唯一AppId根据实际情况看是否需要全局唯一;但是不管是否全局唯一最好让生成的Id有如下属性: 趋势递增:这样在保存数据库的时候,使用索引性能更好; 信息安全:尽量不要连续的,容易发现规律; 关于全局唯一Id生成的方式常见的有类snowflake方式等;

5.限流机制
常用的限流算法包括:令牌桶限流,漏桶限流,计数器限流;

1.令牌桶限流
令牌桶算法的原理是系统以一定速率向桶中放入令牌,填满了就丢弃令牌;请求来时会先从桶中取出令牌,如果能取到令牌,则可以继续完成请求,否则等待或者拒绝服务;令牌桶允许一定程度突发流量,只要有令牌就可以处理,支持一次拿多个令牌;

2.漏桶限流
漏桶算法的原理是按照固定常量速率流出请求,流入请求速率任意,当请求数超过桶的容量时,新的请求等待或者拒绝服务;可以看出漏桶算法可以强制限制数据的传输速度;

3.计数器限流
计数器是一种比较简单粗暴的算法,主要用来限制总并发数,比如数据库连接池、线程池、秒杀的并发数;计数器限流只要一定时间内的总请求数超过设定的阀值则进行限流;

具体基于以上算法如何实现,Guava提供了RateLimiter工具类基于基于令牌桶算法:

RateLimiter rateLimiter = RateLimiter.create(5);
以上代码表示一秒钟只允许处理五个并发请求,以上方式只能用在单应用的请求限流,不能进行全局限流;这个时候就需要分布式限流,可以基于redis+lua来实现;

6.黑名单机制
如何为什么中黑我们这边不讨论,我们可以给每个用户设置一个状态比如包括:初始化状态,正常状态,中黑状态,关闭状态等等;或者我们直接通过分布式配置中心,直接保存黑名单列表,每次检查是否在列表中即可;

7.数据合法性校验
合法性校验包括:常规性校验以及业务校验; 常规性校验:包括签名校验,必填校验,长度校验,类型校验,格式校验等; 业务校验:根据实际业务而定,比如订单金额不能小于0等;

总结
本文大致列举了几种常见的安全措施机制包括:数据加密、数据加签、时间戳机制、AppId机制、限流机制、黑名单机制以及数据合法性校验;当然肯定有其他方式,欢迎补充。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/100229.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java中的枚举是什么?

Java枚举详解 枚举(Enum)是Java编程语言中的一种特殊数据类型,它用于表示一组具名的常量。枚举提供了一种更加类型安全和易于理解的方式来表示常量值,使代码更加清晰和可维护。 为什么需要枚举? 在介绍Java枚举的具…

你知道npm、yarn、pnpm的区别吗?

npm 嵌套的 node_modules 结构 npm 在早期采用的是嵌套的 node_modules 结构,“node_modules” 文件夹通常包含项目依赖的模块。在项目中使用多个依赖并且这些依赖本身也有它们自己的依赖时,就会出现嵌套的 “node_modules” 结构。 嵌套的 “node_mo…

【Redis学习1】Redis持久化机制详解

Redis持久化机制详解 一、Redis为什么需要持久化机制 Redis一般用作缓存,其数据存储在内存中,当Redis宕机后,内存中的数据将会丢失。因此使用缓存的时候,我们经常需要对内存中的数据进行持久化也就是将内存中的数据写入到硬盘中…

Jetpack:004-如何使用文本组件

文章目录 1. 概念介绍2. 使用方法2.1 通用参数2.2 专用参数 3. 示例代码4. 内容总结 我们在上一章回中介绍了Jetpack组件在布局中的对齐方式,本章回中主要介绍文 本组件的使用方法。闲话休提,让我们一起Talk Android Jetpack吧 1. 概念介绍 我们在本章…

YOLOv7改进:SPD-Conv,低分辨率图像和小物体涨点明显,涨点神器!!!

💡💡💡本文属于原创独家改进:SPD-Conv,优势:处理低分辨率图像和小物体等更困难的任务时性能更优 SPD-Conv | 亲测在多个数据集实现暴力涨点,尤其是小物体检测你值得拥有,强烈推荐,独家首发; 收录: YOLOv7高阶自研专栏介绍: http://t.csdnimg.cn/tYI0c ✨…

基于ffmpeg给视频添加时间字幕

FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序,我们可以基于ffmpeg对视频进行各种操作。本文主要介绍基于ffmpeg给视频添加字幕,字幕的内容为视频所播放的时间(故需要安装ffmpeg,具…

Stream 流式编程创建及其常用操作方法

目录 Stream 对象如何创建 Stream 常用的操作方法 1.过滤(Filter) 2.映射(Map) 3.扁平映射(FlatMap) 4.截断(Limit) 5.跳过(Skip) 6.排序&#xff08…

ssti 前置学习

python venv环境 可以把它想象成一个容器,该容器供你用来存放你的Python脚本以及安装各种Python第三方模块,容器里的环境和本机是完全分开的 创建venv环境安装flask #apt install python3.10-venv #cd /opt #python3 -m venv flask1 #cd /opt 选…

吃透底层:从路由到前缀树

前言 今天学到关于路由相关文章,发现动态路由中有一个很常见的实现方式是前缀树,很感兴趣这个算法,故进行记录。 前缀树 Trie(又被叫做字典树)可以看作是一个确定有限状态自动机,尽管边上的符号一般是隐含…

Netty通信在中间件组件中的广泛使用-Dubbo3举例

Netty是一个高性能异步IO通信框架,封装了NIO,对各种bug做了很好的优化解决。所以很多中间件底层的通信都会使用Netty,比如说:Dubbo3,rocketmq,ElasticSearch等。 比方说,我们使用dubbo作为rpc跨…

基于SSM线上课程管理系统设计与实现

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用JSP技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…

C++构造函数

在本文中,您将学习C 中的构造函数。您将学习什么是构造函数,如何创建它以及C 中的构造函数类型。 构造函数是成员函数的一种特殊类型,它在创建对象时会自动对其进行初始化。编译器通过其名称和返回类型将给定的成员函数标识为构造函数。构造函…

网络编程中套接字(socket)介绍(Python示例)

网络编程中套接字(socket)介绍(Python示例) 网络编程就是同一计算机的进程间或者不同的联网计算机之间的通信(交换数据)。 那么,这两台计算机之间用什么传输数据呢?首先你肯定先需要…

各报文段格式集合

数据链路层-- MAC帧 前导码8B:数据链路层将封装好的MAC帧交付给物理层进行发送,物理层在发送MAC帧前,还要在前面添加8字节的前导码(分为7字节的前同步码1字节的帧开始定界符)MAC地址长度6B数据长度46~1500B…

scala 连接 MySQL 数据库案例

1 依赖准备 mysql 8添加&#xff1a; <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.29</version></dependency> mysql 5 添加&#xff1a; <dependency><grou…

爬取微博热榜并将其存储为csv文件

&#x1f64c;秋名山码民的主页 &#x1f602;oi退役选手&#xff0c;Java、大数据、单片机、IoT均有所涉猎&#xff0c;热爱技术&#xff0c;技术无罪 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; 获取源码&#xff0c;添加WX 目录 前言1.…

防止SQL注入攻击的综合解决方案

文章目录 摘要背景和危害性防御措施示例代码&#xff08;Java&#xff09;示例代码&#xff08;PHP&#xff09;示例MySQL命令示例代码&#xff08;Python&#xff09;示例代码&#xff08;C#&#xff0c;使用Entity Framework&#xff09; 进一步防御SQL注入攻击的措施使用ORM…

【Linux】Git使用

一、Git简介 Git 是一个开源的分布式版本控制系统&#xff0c;用于敏捷高效地处理很小或非常大的项目。 Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。 Git 与常用的版本控制工具 CVS, Subversion 等不同&#xff0c;它采用了分布…

Kafka 简介之(学习之路)

正文 一、简介 1.1 概述 Kafka是最初由Linkedin公司开发&#xff0c;是一个分布式、分区的、多副本的、多订阅者&#xff0c;基于zookeeper协调的分布式日志系统&#xff08;也可以当做MQ系统&#xff09;&#xff0c;常见可以用于web/nginx日志、访问日志&#xff0c;消息服务…

原生JS-鼠标拖动

原生JS-鼠标拖动 通过鼠标的点击事件通过h5的属性 通过鼠标的点击事件 步骤&#xff1a; 1. 鼠标按下div。 2. 鼠标移动&#xff0c;div跟着移动 原生js&#xff0c;实现拖拽效果。1. 给被拖拽的div加上 onmousedown 鼠标【按下事件】。鼠标按下的时候&#xff0c;开始监听鼠标…