自留地

API安全

2017-11-01  本文已影响42人  二B铅笔

API安全

数据准备

header:

time:时间戳

token:用户登录信息token jwt

version:版本

did:设备号

......

body:

name:gaozhan

......

客户端加密

1.生成随机AES加密字符串aes_key

2.aes_key对header内容加密 aes_header

3.aes_key对body内容加密 aes_body

4.rsa公钥对aes_key进行加密 rsa_aes_key

传输

0.rsa_aes_key放入header

1.aes_header放入header

2.aes_body 放body

服务端解密

0.RSA私钥对rsa_aes_key解密 得到aes_key

1.aes_key对header解密

2.校验时间戳时效性/版本有效性/用户访问权限

3.aes_key对aes_body解密

代码示例

github: https://github.com/gaozhan3253/app-restful-api-demo

片段

laravel中间件:


     //获取rsa_aes_key

     $rsa_aes_key=$request->header('rsa-aes-key');

      //不存在rsa加密字符串时

       if(empty($rsa_aes_key)) {

            return  response()->json(['message'=>'非法访问','status_code'=>401],401);

       }

      //解密rsa加密字符串 得到aes加密字符串

             $aes_key= RsaOptions::decrypt($rsa_aes_key);

      if(empty($aes_key)) {

              return  response()->json(['message'=>'非法访问','status_code'=>401],401);

       }

      //接收aes加密的header

          $aes_header=$request->header('aes-header');

       if(empty($aes_header)) {

           return  response()->json(['message'=>'无加密header信息','status_code'=>401],401);

       }

       //解密aes加密字符串

       $headers= AesOptions::aes128cbcDecrypt($aes_header,$aes_key);

       $headers=json_decode($headers);

       //验证是否存在必须time字段 因为time字段绝对存在

        if(empty($headers) ||empty($headers->time)) {

              return   response()->json(['message'=>'无效header','status_code'=>401],401);

         }

     //验证唯一性

       $onlyToken=$headers->onlytoken;

       //$onlyToken=$headers->onlytoken.rand(000001,999999);//测试用 唯一性处理

       $onlyTokenHasBool= Cache::store('redis')->has($onlyToken);

       if($onlyTokenHasBool) {

               return   response()->json(['message'=>'重复请求','status_code'=>401],401);

          }else{

               Cache::store('file')->put($onlyToken,'',5);

         }

        //验证时效性

         $requestTime=$headers->time;//请求的时间戳

           $expiresTime=strtotime('-'. env('API_EXPIRES_TIME',1) .' minute');//请求有效时间

         if($expiresTime>$requestTime) {

                return    response()->json(['message'=>'请求已过期','status_code'=>401],401);

          }

       //将aes_key保存 用于将返回信息加密

       define('AES_KEY',$aes_key);

        //将解密后的header写回header中

         if(count($headers)){

          foreach($headers   as  $key=>$value){

                //jwt验证token格式化处理

                if($key=='token'){

                      $key='authorization';

                      $value='bearer '.$value;

                   }

             $request->headers->set($key,$value);

        }

       }

        //获取body

         $aes_body=$request->get('aes-body','');

          //解密aes加密字符串

            $bodys= AesOptions::aes128cbcDecrypt($aes_body,$aes_key);

             $bodys=json_decode($bodys);

             if(count($bodys)){

              foreach($bodys  as   $key=>$value){

                     $request->offsetSet($key,$value);

               }

           }

上一篇下一篇

猜你喜欢

热点阅读