来源:my.oschina.net/OutOfMemory/blog/3131916 前言最近有个项目需要对外提供一个接口,提供公网域名进行访问,而且接口和交易订单有关,所以安全性很重要;这里整理了一下常用的一些安全措施以及具体如何去实现。 安全措施个人觉得安全措施大体来看主要在两个方面:
1.数据加密我们知道数据在传输过程中是很容易被抓包的,如果直接传输比如通过http协议,那么用户传输的数据可以被任何人获取;所以必须对数据加密,常见的做法对关键字段加密比如用户密码直接通过md5加密;现在主流的做法是使用https协议,在http和tcp之间添加一层加密层(SSL层),这一层负责数据的加密和解密; 2.数据加签数据加签就是由发送者产生一段无法伪造的一段数字串,来保证数据在传输过程中不被篡改;你可能会问数据如果已经通过https加密了,还有必要进行加签吗?数据在传输过程中经过加密,理论上就算被抓包,也无法对数据进行篡改;但是我们要知道加密的部分其实只是在外网,现在很多服务在内网中都需要经过很多服务跳转,所以这里的加签可以防止内网中数据被篡改; 3.时间戳机制数据是很容易被抓包的,但是经过如上的加密,加签处理,就算拿到数据也不能看到真实的数据;但是有不法者不关心真实的数据,而是直接拿到抓取的数据包进行恶意请求;这时候可以使用时间戳机制,在每次请求中加入当前的时间,服务器端会拿到当前时间和消息中的时间相减,看看是否在一个固定的时间范围内比如5分钟内;这样恶意请求的数据包是无法更改里面时间的,所以5分钟后就视为非法请求了; 4.AppId机制大部分网站基本都需要用户名和密码才能登录,并不是谁来能使用我的网站,这其实也是一种安全机制;对应的对外提供的接口其实也需要这么一种机制,并不是谁都可以调用,需要使用接口的用户需要在后台开通appid,提供给用户相关的密钥;在调用的接口中需要提供 appid+密钥,服务器端会进行相关的验证; 5.限流机制本来就是真实的用户,并且开通了appid,但是出现频繁调用接口的情况;这种情况需要给相关appid限流处理,常用的限流算法有令牌桶和漏桶算法; 6.黑名单机制如果此appid进行过很多非法操作,或者说专门有一个中黑系统,经过分析之后直接将此appid列入黑名单,所有请求直接返回错误码; 7.数据合法性校验这个可以说是每个系统都会有的处理机制,只有在数据是合法的情况下才会进行数据处理;每个系统都有自己的验证规则,当然也可能有一些常规性的规则,比如身份证长度和组成,电话号码长度和组成等等; 如何实现以上大体介绍了一下常用的一些接口安全措施,当然可能还有其他我不知道的方式,希望大家补充,下面看看以上这些方法措施,具体如何实现; 1.数据加密现在主流的加密方式有对称加密和非对称加密
两种方式各有优缺点,而https的实现方式正好是结合了两种加密方式,整合了双方的优点,在安全和性能方面都比较好; 对称加密和非对称加密代码实现,jdk提供了相关的工具类可以直接使用,此处不过多介绍;关于https如何配置使用相对来说复杂一些,可以参考本人的之前的文章HTTPS分析与实战 2.数据加签数据签名使用比较多的是md5算法,将需要提交的数据通过某种方式组合和一个字符串,然后通过md5生成一段加密字符串,这段加密字符串就是数据包的签名,可以看一个简单的例子: str:参数1={参数1}&参数2={参数2}&……&参数n={参数n}$key={用户密钥}; 注意最后的用户密钥,客户端和服务端都有一份,这样会更加安全; 3.时间戳机制解密后的数据,经过签名认证后,我们拿到数据包中的客户端时间戳字段,然后用服务器当前时间去减客户端时间,看结果是否在一个区间内,伪代码如下:
4.AppId机制生成一个唯一的AppId即可,密钥使用字母、数字等特殊字符随机生成即可;生成唯一AppId根据实际情况看是否需要全局唯一;但是不管是否全局唯一最好让生成的Id有如下属性:
关于全局唯一Id生成的方式常见的有类snowflake方式等; 5.限流机制常用的限流算法包括:固定窗口计数器算法、滑动窗口计数器算法、漏桶限流、令牌桶限流 固定窗口计数器算法规定我们单位时间处理的请求数量。比如我们规定我们的一个接口一分钟只能访问10次的话。使用固定窗口计数器算法的话可以这样实现:给定一个变量counter来记录处理的请求数量,当1分钟之内处理一个请求之后counter+1,1分钟之内的如果counter=100的话,后续的请求就会被全部拒绝。等到 1分钟结束后,将counter回归成0,重新开始计数(ps:只要过了一个周期就讲counter回归成0)。 这种限流算法无法保证限流速率,因而无法保证突然激增的流量。比如我们限制一个接口一分钟只能访问10次的话,前半分钟一个请求没有接收,后半分钟接收了10个请求。 滑动窗口计数器算法算的上是固定窗口计数器算法的升级版。滑动窗口计数器算法相比于固定窗口计数器算法的优化在于:它把时间以一定比例分片比如一分钟分为6个区间,每个区间为10s。每过一定区间的时间,就抛弃最前面的一个区间,如下图所示。如果当前窗口的请求数量超过了限制数量的话,就拒绝后续请求。 很显然:当滑动窗口的格子划分的越多,滑动窗口的滚动就越平滑,限流的统计就会越精确。 漏桶算法我们可以把发请求的动作比作成注水到桶中,我们处理请求的过程可以比喻为漏桶漏水。我们往桶中以任意速率流入水,以一定速率流出水。当水超过桶流量则丢弃,因为桶容量是不变的,保证了整体的速率。如果想要实现这个算法的话也很简单,准备一个队列用来保存请求,然后我们定期从队列中拿请求来执行就好了。 令牌桶算法令牌桶算法也比较简单。和漏桶算法算法一样,我们的主角还是桶(这限流算法和桶过不去啊)。不过现在桶里装的是令牌了,请求在被处理之前需要拿到一个令牌,请求处理完毕之后将这个令牌丢弃(删除)。我们根据限流大小,按照一定的速率往桶里添加令牌。 具体基于以上算法如何实现,Guava提供了RateLimiter工具类基于基于令牌桶算法: RateLimiter rateLimiter = RateLimiter.create(5); 以上代码表示一秒钟只允许处理五个并发请求,以上方式只能用在单应用的请求限流,不能进行全局限流;这个时候就需要分布式限流,可以基于redis+lua来实现; 6.黑名单机制如何为什么中黑我们这边不讨论,我们可以给每个用户设置一个状态比如包括:初始化状态,正常状态,中黑状态,关闭状态等等;或者我们直接通过分布式配置中心,直接保存黑名单列表,每次检查是否在列表中即可; 7.数据合法性校验合法性校验包括:
总结本文大致列举了几种常见的安全措施机制包括:数据加密、数据加签、时间戳机制、AppId机制、限流机制、黑名单机制以及数据合法性校验;当然肯定有其他方式,欢迎补充。 (完) Java团长 专注于Java干货分享 扫描上方二维码获取更多Java干货 |
|