php-app开发接口加密详解


Posted in PHP onApril 18, 2018

自己平时工作中用到的一套接口加密规则,记录下来以后用:

/**
inc 
解析接口
客户端接口传输规则:
1.用cmd参数(base64)来动态调用不同的接口,接口地址统一为 http://a.lovexpp.com
2.将要传过来的参数组成一个数组,数组添加timestamp元素(当前时间戳,精确到秒),将数组的键值按照自然排序从大到小排序
3.将数组组成 key=val&key=val的形式的字符串,将字符串与XPP_KEY连接在一起,用md5加密一次(32位小写),得到sign
4.将sign添加到参数数组中
5.将参数数组转换成json用post请求请求接口地址,key值为param
服务端接口解析规则:
1.接收参数param,将结果解析json得到参数数组
2.取出sign,去掉参数数组中的sign
3.将参数数组key值按照自然排序从大到小排序
4.将排序后的参数数组按照key=val&key=val的形式组成字符串,将字符串与XPP_KEY连接,用md5加密一次(32位小写),得到sign
5.将sign与客户端传过来的sign进行比对,如不一样则可能是中途被篡改参数,服务器拒绝此次请求
6.将sign与session中的sign对比,如果一样,则为重复提交,服务器拒绝此次请求
7.此次的sign存入session
8.执行路由cmd(base64解析后),将参数带到该方法中
*/
 
$xpp_key = "xxx";
 
//接收参数param,将结果解析json得到参数数组
$param = json_decode($_POST['param'] , true);
 
//取出sign,去掉参数数组中的sign
$client_sign = $param['sign'];
unset($param['sign']);
 
//将参数数组key值按照自然排序从大到小排序
krsort($param);
 
//将排序后的参数数组按照key=val&key=val的形式组成字符串,将字符串与XPP_KEY连接,用md5加密一次(32位小写),得到sign
$sb = '';
foreach($param as $key=>$val){
  $sb .= $key . '=' . $val . '&';
}
$sb .= $xpp_key;
$server_sign = md5($sb);
 
//将sign与客户端传过来的sign进行比对,如不一样则可能是中途被篡改参数,服务器拒绝此次请求
if($server_sign !== $client_sign){
  echo json_encode(array('code'=>'invalid request'));
  exit;
}
 
//将sign与session中的sign对比,如果一样,则为重复提交,服务器拒绝此次请求
if($server_sign == $_SESSION['last_sign']){
  echo json_encode(array('code'=>'Repeated requests'));
  exit();
}
 
//此次的sign存入session
$_SESSION['last_sign'] = $server_sign;
 
//执行路由cmd(base64解析后),将参数带到该方法中
$cmd = base64_decode($param['cmd']);
list($__controller,$__action) = explode('-' , $cmd);
 
// 设置请求参数
unset($param['cmd']);
unset($param['timestamp']);
foreach($param as $key => $val){
  $_REQUEST[$key] = $val;
}

客户端代码demo:

package com.xpplove.newxpp.activity;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import org.apache.commons.codec.binary.Base64;
import android.os.Bundle;
import com.alibaba.fastjson.JSON;
import com.xpplove.newxpp.BaseActivity;
import com.xpplove.newxpp.bean.Params;
import com.xpplove.newxpp.net.NetPostTask;
import com.xpplove.newxpp.utils.DensityUtil;
public class TestActivity extends BaseActivity {
  private String url = "http://c.lovexpp.com/";
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    loadMesage();
  }
  private void loadMesage() {
    Base64 base64 = new Base64();
    Map<String, String> paramsMap = new HashMap<String, String>();
    paramsMap.put("timestamp", (System.currentTimeMillis() / 1000 + ""));
    String cmd = new String(base64.encode("user-camList".getBytes()));
    String dcmd = new String(base64.decode(cmd.getBytes()));
    paramsMap.put("cmd", cmd);
    paramsMap.put("sign", getString(paramsMap));
    String str = getKeyValues(paramsMap);
    paramsMap = new HashMap<String, String>();
    paramsMap.put("param", str);
    Params params = new Params();
    params.listener = this;
    params.url = url;
    //new NetWorkTask().executeProxy(params);
    new NetPostTask(paramsMap).executeProxy(params);
  }
  @Override
  public void onGetResult(int errorCode, Object result) {
    super.onGetResult(errorCode, result);
    System.out.println();
  }
  private String getString(Map<String, String> paramsMap) {
    TreeMap tm = new TreeMap(paramsMap);
    Iterator i = tm.descendingMap().entrySet().iterator();
    StringBuffer buffer = new StringBuffer();
    while (i.hasNext()) {
      buffer.append(i.next() + "&");
    }
    buffer.append(AppKey);
    return DensityUtil.MD5(buffer.toString());
  }
  // 得到键值对
  private String getKeyValues(Map<String, String> paramsMap) {
    TreeMap tm = new TreeMap(paramsMap);
    Iterator i = tm.descendingKeySet().iterator();
    String jsonText = JSON.toJSONString(tm.descendingMap(), true);
    return jsonText;
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
PHP新手上路(五)
Oct 09 PHP
使用PHP遍历文件夹与子目录的函数代码
Sep 26 PHP
php 的加密函数 md5,crypt,base64_encode 等使用介绍
Apr 09 PHP
很让人受教的 提高php代码质量36计
Sep 05 PHP
LotusPhp笔记之:Cookie组件的使用详解
May 06 PHP
探讨如何把session存入数据库
Jun 07 PHP
解析PHP的session过期设置
Jun 29 PHP
ThinkPHP添加更新标签的方法
Dec 05 PHP
Laravel中使用自己编写类库的3种方法
Feb 10 PHP
php 实现301重定向跳转实例代码
Jul 18 PHP
PHP信号处理机制的操作代码讲解
Apr 19 PHP
php模拟实现斗地主发牌
Apr 22 PHP
PHPMAILER实现PHP发邮件功能
Apr 18 #PHP
PHP实现数据库的增删查改功能及完整代码
Apr 18 #PHP
php无限级评论嵌套实现代码
Apr 18 #PHP
PHP实现负载均衡下的session共用功能
Apr 17 #PHP
PHP代码重构方法漫谈
Apr 17 #PHP
php微信公众号开发之现金红包
Apr 16 #PHP
PHP闭包定义与使用简单示例
Apr 13 #PHP
You might like
php异步多线程swoole用法实例
2014/11/14 PHP
wampserver改变默认网站目录的办法
2015/08/05 PHP
PHP MVC框架路由学习笔记
2016/03/02 PHP
thinkPHP实现基于ajax的评论回复功能
2018/06/22 PHP
jquery、js调用iframe父窗口与子窗口元素的方法整理
2014/07/31 Javascript
JQuery中使用on方法绑定hover事件实例
2014/12/09 Javascript
jQuery使用drag效果实现自由拖拽div
2015/06/11 Javascript
详解AngularJS 模块化
2017/06/14 Javascript
JavaScript实现简单图片轮播效果
2017/08/21 Javascript
详解使用webpack构建多页面应用
2017/12/21 Javascript
vue的style绑定background-image的方式和其他变量数据的区别详解
2018/09/03 Javascript
JS实现二维数组元素的排列组合运算简单示例
2019/01/28 Javascript
Vue动态路由缓存不相互影响的解决办法
2019/02/19 Javascript
javascript 构建模块化开发过程解析
2019/09/11 Javascript
Node.js API详解之 assert模块用法实例分析
2020/05/26 Javascript
Vue-cli打包后如何本地查看的操作
2020/09/02 Javascript
全局安装 Vue cli3 和 继续使用 Vue-cli2.x操作
2020/09/08 Javascript
[56:42]完美世界DOTA2联赛循环赛 Matador vs Forest 第二场 11.06
2020/11/06 DOTA
使用Python的Twisted框架编写简单的网络客户端
2015/04/16 Python
python中requests库session对象的妙用详解
2017/10/30 Python
对django的User模型和四种扩展/重写方法小结
2019/08/17 Python
python如何保存文本文件
2020/06/07 Python
解决django migrate报错ORA-02000: missing ALWAYS keyword
2020/07/02 Python
Node.js 和 Python之间该选择哪个?
2020/08/05 Python
完美解决torch.cuda.is_available()一直返回False的玄学方法
2021/02/06 Python
Engel & Bengel官网:婴儿推车、儿童房家具和婴儿设备
2019/12/28 全球购物
3D空间设计学生找工作的自我评价
2013/10/28 职场文书
捐款倡议书范文
2014/02/02 职场文书
高考励志标语
2014/06/05 职场文书
纪检干部现实表现材料
2014/08/21 职场文书
入党函调证明材料
2014/12/24 职场文书
结婚保证书
2015/01/16 职场文书
绍兴鲁迅故居导游词
2015/02/09 职场文书
班主任开场白
2015/06/01 职场文书
mysql下的max_allowed_packet参数设置详解
2022/02/12 MySQL
一文了解MySQL二级索引的查询过程
2022/02/24 MySQL