如何保证 请求的安全
- url参数防篡改
- sign 防重放
- 来源(身份)是否合法
签名设计方案
设计 客户端规则
给不同客户端 如(app)分配对应的 商户 key, secret 用来确认请求来自 哪一端
key :xxxAndroid.3.14
secret : dfsdfsfxxxxx (用来加密sign)
假设 url 传递的参数为
id: wxd930ea5d5a258f4f
device_info: xxx
body: test
nonce_str: ibuaiVcKdpRxkhJA (该参数是防重放用 ,每次请求随机生成一个 随机字符串,此处可换成 时间戳,做范围时间内sign 失效)
第一步:对参数按照key=value的格式,并按照参数名ASCII字典序排序如下:
stringTemp="body=test&device_info=xxx&id=wxd930ea5d5a258f4f&nonce_str=ibuaiVcKdpRxkhJA";
第二步:拼接API密钥生成Sign:
将上面 第一步生成的stringTemp 拼接上 客户端分配上的 secret
stringSignTemp=stringTemp+"&secret=dfsdfsfxxxxx" //注:secret为后台返回的的密钥key,对应的secret
//"body=test&device_info=xxx&id=wxd930ea5d5a258f4f&nonce_str=ibuaiVcKdpRxkhJA&secret=dfsdfsfxxxxx"
sign=hash_hmac("sha256",stringSignTemp,key).toUpperCase();
//"6A9AE1657590FD6257D693A078E1C3E4BB6BA4DC30B23E0EE2496E54170DACD6"
第三步:最终得到最终发送的数据:
id: wxd930ea5d5a258f4f
device_info: xxx
body: test
nonce_str: ibuaiVcKdpRxkhJA (该参数是防重放用 ,每次请求随机生成一个 随机字符串)
key=xxxAndroid.3.14 (可放在header)
sign: 6A9AE1657590FD6257D693A078E1C3E4BB6BA4DC30B23E0EE2496E54170DACD6(可放在header)
设计 服务端验签规则
第一步:将前端请求参数(除去key
,sign
后的)按照key=value的格式,并按照参数名ASCII字典序排序如下:
stringTemp="body=test&device_info=xxx&id=wxd930ea5d5a258f4f&nonce_str=ibuaiVcKdpRxkhJA";
第二步:根据key
去数据库查找对应的secret
,拼接API密钥生成Sign:
stringSignTemp=stringTemp+"&secret=dfsdfsfxxxxx"
serverSign=hash_hmac("sha256",stringSignTemp,key).toUpperCase();
第三步: 对吧后端生成的 sign
是否 与前端传递的sign
值 是否一致
if(serverSign ==sign){
//todo
}