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