image.png

API 接口安全性设计

实现约定规则

调用方按照规则加密,传输对应参数

服务方按照规则解密

防止被其他人调用

appKey & signKey

  • 原理

  • 通过 appKey 标识不同调用方

  • 利用 signKey 和 传入参数 生成 sign 进行加密

  • signKey 只在本地加密,不参与网络传输

  • 比较好的加密方式是 通过 rsa 加密的方式。 公钥给对方,用于解密。私钥自己保存,用于加密

Token

  • 原理

  • 0 提前给调用方分配好 用户名和密码

  • 1 用户登录向服务器提供认证信息(如账号和密码),服务器验证成功后返回Token给客户端;

  • 2客户端将Token保存在本地,后续发起请求时,携带此Token;(只携带 token,不带上 appKey。 需要接口提供方根据 token 找出是哪个调用方)

  • 3服务器检查Token的有效性,有效则放行,无效(Token错误或过期)则拒绝。

  • 安全隐患

  • Token 被劫持之后,可以伪造请求和篡改参数

  • 解决方案:服务方配置 ip 白名单

防止接口请求参数被更改

将请求中的所有参数和值按照字典升序排序,生成字符串,然后利用 signKey 进行加密

具体流程

  • 1 按照请求参数名的字母升序排列非空请求参数(包含AccessKey),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA;

  • 2在stringA最后拼接上Secretkey得到字符串stringSignTemp;

  • 3对stringSignTemp进行MD5运算,并将得到的字符串所有字符转换为大写,得到sign值。

如何防止中间人替换返回结果

服务接口方在返回结果的时候,同样带上 验签字段。

调用方在收到返回的时候,根据 验签字段,校验是否符合规则。如果符合规则,则说明未被替换

防止接口被重放

nonce + timestamp

但是是否存在意义?服务端是否应该做接口幂等?

nonce指唯一的随机字符串,用来标识每个被签名的请求。通过为每个请求提供一个唯一的标识符,服务器能够防止请求被多次使用(记录所有用过的nonce以阻止它们被二次使用)。

然而,对服务器来说永久存储所有接收到的nonce的代价是非常大的。可以使用timestamp来优化nonce的存储。

其他安全性

IP 白名单

接口设计常用字段

appId 调用方唯一标识

method 接口调用方法 (或者以 url 区分)

version 调用接口的版本

加密相关

  • sign_type 加密算法

  • sign 加密后的字符串,用于接口提供方校验

timstamp

  • 标识发出请求时间

  • 接口提供方根据时间判断是否要继续处理请求

  • 业务层面区分

  • 防止中间人回放攻击

notify_url

  • 回调的 url 。接口提供方主动通知接口调用方指定页面路径

biz_content

  • 接口请求参数的集合 的字符串 (或者以接口字段的形式暴露出来)

其他相关

oath2.0

  • 主要是 客户,平台,开发商之间的关系

  • 用于 客户授权开发商获取/操作客户在平台上的信息

原文出处-知乎作者:天龙