图片

前言

在最近一个项目中,我们需要设计一个对外接口来提供公网域名访问,并且由于接口涉及交易订单的处理,安全性显得尤为重要。为此,我总结了一些常见的安全措施及其具体实现方法,希望能为您提供帮助。

安全措施

从整体来看,安全措施可以归纳为两个主要方面:

  1. 确保数据在传输过程中的安全;
  2. 在数据到达服务器后,服务器如何识别数据并避免受到攻击。接下来详细介绍相关的安全措施。

1. 数据加密

数据在传输过程中容易被拦截,尤其是通过 HTTP 协议传输时,用户的数据可能会被他人获取。因此,加密数据是必须的。通常,关键字段,如用户密码,采用 MD5 等方式进行加密。现代主流做法是使用 HTTPS 协议,在 HTTP 和 TCP 之间添加了一层加密(SSL层),负责数据的加解密。

2. 数据加签

数据加签是由发送者生成一段不可伪造的字符串,用于保证数据在传输过程中不被篡改。虽然数据通过 HTTPS 加密后,理论上即使被拦截也无法被更改,但在很多场景中,数据可能通过多次内网转发,这时加签能有效防止内网中的数据被篡改。

3. 时间戳机制

尽管数据经过加密和加签处理,恶意用户仍可能利用抓包工具发起恶意请求。时间戳机制在请求中加入当前时间,服务器将当前时间与请求中的时间进行对比,判断是否在规定的时间范围内(例如5分钟)。这样,即使恶意请求抓取了数据包,其内部的时间也无法更改,超出时间范围的请求将被视为非法。

4. AppId 机制

大多数网站都要求用户通过用户名和密码登录,这本身就是一种安全机制。对外接口同样需要类似机制,用户在后台申请 AppId,并获得相关的密钥。接口调用时需要提供 AppId 和密钥,服务器会进行验证。

5. 限流机制

即使是合法用户,频繁调用接口也可能导致系统过载。因此,应该对相关 AppId 实施限流。常用的限流算法包括令牌桶和漏桶算法。

6. 黑名单机制

若某个 AppId 进行多次非法操作,可以将其列入黑名单,所有请求将直接返回错误码。

7. 数据合法性校验

数据合法性校验是系统的基本处理机制,只有在数据合法的情况下才进行处理。每个系统应有自己的验证规则,包括身份证、电话号码的长度和组成等。

如何实现

上述安全措施为接口设计提供了基础,接下来讨论如何具体实现这些措施。

1. 数据加密

主流的加密方式包括对称加密和非对称加密:

  1. 对称加密:加密和解密使用相同的密钥。常用的算法有 DES 和 AES,优点是计算速度快,但双方必须事先约定并保存好密钥,一旦密钥泄露,信息安全就会受到威胁。
  2. 非对称加密:服务端生成一对密钥,私钥保留在服务器,公钥可以对外发布。虽然更安全,但加解密速度慢,广泛使用 RSA 算法。

这两种方式各有优缺点,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,密钥可随机生成字母、数字和特殊字符。根据实际情况决定是否需要全局唯一,但最好生成的 ID 满足以下属性:

  1. 趋势递增:有利于数据库索引性能。
  2. 信息安全:避免连续生成,防止被推测。

5. 限流机制

常见的限流算法包括固定窗口计数器、滑动窗口计数器、漏桶限流和令牌桶限流。

固定窗口计数器算法

设定单位时间内的请求处理数量。例如,每分钟只能访问10次。实现方式是通过一个计数器记录请求数量,超过限额则拒绝后续请求。

图片

滑动窗口计数器算法

相比固定窗口计数器算法的升级版,将时间分为多个区间进行处理。当前窗口的请求数量超过限制时,拒绝后续请求。

图片

漏桶算法

将请求处理过程比作注水到桶中,水流出桶的速率是固定的,超出桶的容量部分将被丢弃。可通过队列保存请求并定期执行。

图片

令牌桶算法

请求在处理前需要获取令牌,处理后将其丢弃。可根据限流大小,按一定速率往桶中添加令牌。

图片

对于基于令牌桶算法的实现,Guava 提供了 RateLimiter 工具类:

RateLimiter rateLimiter = RateLimiter.create(5);  

以上代码表示每秒最多处理五个并发请求。此方式仅适用于单应用请求限流,若需全局限流,可结合 Redis 和 Lua 实现。

6. 黑名单机制

可为每个用户设置状态,例如初始化、正常、中黑和关闭等。通过分布式配置中心保存黑名单列表,实时检查请求是否在黑名单中。

7. 数据合法性校验

合法性校验包括:

  1. 常规性校验:签名校验、必填校验、长度校验、类型校验和格式校验等;
  2. 业务校验:依据实际业务规则,例如订单金额不能小于 0 等。