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

前言

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

安全措施

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

1.数据加密

咱们知道数据在传输过程当中是很容易被抓包的,若是直接传输好比经过http协议,那么用户传输的数据能够被任何人获取;因此必须对数据加密,常见的作法对关键字段加密好比用户密码直接经过md5加密;如今主流的作法是使用https协议,在http和tcp之间添加一层加密层(SSL层),这一层负责数据的加密和解密;数据库

2.数据加签

数据加签就是由发送者产生一段没法伪造的一段数字串,来保证数据在传输过程当中不被篡改;你可能会问数据若是已经经过https加密了,还有必要进行加签吗?数据在传输过程当中通过加密,理论上就算被抓包,也没法对数据进行篡改;可是咱们要知道加密的部分其实只是在外网,如今不少服务在内网中都须要通过不少服务跳转,因此这里的加签能够防止内网中数据被篡改;安全

3.时间戳机制

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

4.AppId机制

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

5.限流机制

原本就是真实的用户,而且开通了appid,可是出现频繁调用接口的状况;这种状况须要给相关appid限流处理,经常使用的限流算法有令牌桶和漏桶算法;并发

6.黑名单机制

若是此appid进行过不少非法操做,或者说专门有一个中黑系统,通过分析以后直接将此appid列入黑名单,全部请求直接返回错误码;app

7.数据合法性校验

这个能够说是每一个系统都会有的处理机制,只有在数据是合法的状况下才会进行数据处理;每一个系统都有本身的验证规则,固然也可能有一些常规性的规则,好比身份证长度和组成,电话号码长度和组成等等;tcp

如何实现

以上大致介绍了一下经常使用的一些接口安全措施,固然可能还有其余我不知道的方式,但愿你们补充,下面看看以上这些方法措施,具体如何实现;分布式

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=5*60*1000;//超时时间
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机制、限流机制、黑名单机制以及数据合法性校验;固然确定有其余方式,欢迎补充。

相关文章
相关标签/搜索