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
-
主要是 客户,平台,开发商之间的关系
-
用于 客户授权开发商获取/操作客户在平台上的信息