1.API接口
一般指restful http接口,安全手段也可以延伸到函数接口.
2.接口参数示例
{
"金额": 100,
"扣款账户":"user1",
"收款账户":"user2"
}
3.API接口需要防范的攻击
- 防篡改攻击
篡改扣款金额
{
"金额": 10000,
"扣款账户":"user1",
"收款账户":"user2"
}
- 防重放攻击
将参数不动,再次调用api接口,造成重复扣款.
- 防伪装攻击
伪装收款账户或付款账户
{
"金额": 100,
"扣款账户":"user1",
"收款账户":"user5"
}
- 其他(本文不涉及)
其他如参数加密,防止明文传输, 需要使用https协议.
使用https协议时,需要防止中间人攻击,需要用到校验客户端和服务端两端证书.
4.基于timestamp和nonce的方案
- 事先向接口管理员申请: appId , appKey (appKey需要保密,不在网络传输中直接使用)
- 参数
{
"appId":1234,
"时间戳": 1684724412,
"nonce随机数": "b4ea0a2c-08cd-4001-57f0-e75b26c2e78f",
"金额": 100,
"收款账户":"user2",
"md5摘要签名": "fa7faaa7b234414675992ae62448e35e"
}
- MD5摘要签名生成规则:
将所有参数按照一定的顺序排列组合在一起,例如字符升序. 然后再拼接上appKey
appId=1234+时间戳=1684724412+nonce随机数=b4ea0a2c-08cd-4001-57f0-e75b26c2e78f+金额=100+收款账户=user2+appKey=47ea511e-9f62-d62d-cdba-612d0f46dd04
再计算md5摘要
最后发送的数据需要去掉 appKey, 加上摘要结果.
- 服务器端验证
- 先验证时间戳,拒绝60s(或其他时间)以前的请求. 当攻击者采用重放攻击时,可以过滤掉大部分请求,减轻服务器压力.
- 验证appId是否是已经注册的用户,能过滤掉无效请求,伪装用户的请求.
- 在该appId名下,是否已经处理过包含 “nonce随机数”的请求,如果已经处理过,则拒接. 服务器可以用redis实现该功能. 此字段可以防60s内的重放攻击.
- 服务器根据appId获取到内部存储的appKey,根据预定的参数组合方式(不包含客户端发送的md5摘要签名),同服务器端一样,计算参数的md5摘要.
- 比较服务器自己计算的摘要签名与客户端发送参数中的摘要签名, 如果相同则参数合法.
此摘要可以防止篡改攻击,例如攻击者修改金额,或者收款账户. 因为appKey是保密的,攻击者篡改参数后,无法计算出合法的摘要签名.
- appId与appKey键值对,可以防伪装攻击. 只有客户appId自己和服务器才知道对应的appKey,做签名验证通过,说明用户的身份验证通过. 如果用户自身不小心泄露appKey,可向管理员申请重新生成新的.