接口加密的实现(原创)

    目的:

  1,防止恶意无限访问API;

  2,对客户端进行安全验证;

  3,所有接口都走https请求。

   预期:

1,暴露的api接口只有有限的时间能够访问到,防止无线次数访问;

2,signature每次访问都会变化,一个客户端的一次请求只对应一个signature;

3,客户端和服务端同事存储应用密钥(AppSecret),传输过程中进行加密传输;

4,服务端约定加密算法,当客户端发送请求后,所有加密的值拼接到url上,服务端对该次请求进行验证,如果验证通过才去返回相应数据,传输更加安全;

5,能够对接多个用户,扩展性相对较好;

6,https加密传输,安全性高。

    伪代码 :

客户端发送请求:

key
value
备注
AppId 应用id  
AppSecret 应用密钥  
timestamp 请求发送时的时间戳  
noncestr 随机数  
signature 签名 需要结合以上内容进行计算

签名算法:

$string=AppId+noncestr+signature+timestamp;

Signature =md5(md5($string).$AppSecret);

 

未加密前的请求地址:http://www.a.com?AppId=1&timestamp=2&noncestr=a

加密请求如下:https://www.a.com?AppId=1&noncestr=aaa&timestamp=2&signature=789

 

服务端接收请求:

 1,查询数据库,或者设置白名单,找到该Appid对应的AppSecret,即服务端定义合同密钥

$AppSecret='具体密钥';

1,获取url的所有参数,AppId=1&noncestr=aaa&timestamp=2&signature=789

2,把字符串转换成数组

 $Parameters=array(

'AppId'=>'1',

‘noncestr’=>'aaa',

'timestamp'=>'2',

'signature'=>'789'

);

3, 对当前传入参数进行加密运算

$server_signature=MD5(MD5($Parameters['AppId']+$Parameters['noncestr']+$Parameters['timestamp'])+$AppSecret);

4,和传入的$Parameters['signature']进行比较,如果相等则证明该次访问安全。

 

------------------------------------------------------华丽分割线------------------------------------------------------------------------------------

1,客户端发送的加密请求暴露怎么办,能一直访问吗?

if((服务器当前时间戳-当前url的毫秒值)>2分钟){

echo '当前url访问超时';

}

也就是说,暴露的url只能用2分钟,2分钟后这个url就不能请求道数据了,开发阶段可以将时间增大,这个时间可以自己定义,只要发送的请求在有效的时间得到相应就可以,生产环境的话,理论上可以5-10秒足够。

 

 

2,适用场景是什么?有什么缺点?

适用于客户端的数据传输,app的接口数据传输(如果不考虑认为反编译app的话);

缺点在于,如果使用的网站也是使用接口,那么存储加密算法必然会在前端(jquery)上做处理,加密算法及密钥都会暴露,加密无意义。

 

 

3,这样的好处?

      通过加盐方式,隐藏用户的AppSecret,如果发现当前密钥有风险,可以直接上服务端重新生成(借鉴了微信公众平台),易于扩展;

      服务端验证加密,通过才去返回数据;可以对多个客户端提供api接口服务。

 

4,能对ip进行限制吗?

$_config['whitelist']=array( '192.168.1.1','192.144.23.4');

        if (   !   in_array('通过php获取当前ip地址',$_config['whitelist']))
        {
             echo '用户不在白名单内!不能请求到数据';
        }

posted on 2017-03-18 16:39  ziyi_ang  阅读(1014)  评论(0编辑  收藏  举报

导航