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小偷相关截取函数备忘
Nov 28 PHP
php数组比较实现查找连续数的方法
Jul 29 PHP
smarty中改进truncate使其支持中文的方法
May 30 PHP
PHP实现图片批量打包下载功能
Mar 01 PHP
PHP 二维关联数组根据其中一个字段排序(推荐)
Apr 04 PHP
PHP简单实现二维数组赋值与遍历功能示例
Oct 19 PHP
php获取微信基础接口凭证Access_token
Aug 23 PHP
PHP hebrev()函数用法讲解
Feb 21 PHP
PHP中常用的三种设计模式详解【单例模式、工厂模式、观察者模式】
Jun 14 PHP
PHP call_user_func和call_user_func_array函数的简单理解与应用分析
Nov 25 PHP
thinkphp框架类库扩展操作示例
Nov 26 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
thinkPHP中多维数组的遍历方法
2016/01/09 PHP
php实现查询功能(数据访问)
2017/05/23 PHP
PHP7基于curl实现的上传图片功能
2018/05/11 PHP
使用prototype.js进行异步操作
2007/02/07 Javascript
Javascript 函数对象的多重身份
2009/06/28 Javascript
jquery中eq和get的区别与使用方法
2011/04/14 Javascript
使用jQuery清空file文件域的解决方案
2013/04/12 Javascript
JavaScript几种数组去掉重复值的方法推荐
2016/04/12 Javascript
angularjs 表单密码验证自定义指令实现代码
2016/10/27 Javascript
element-ui 限制日期选择的方法(datepicker)
2018/05/16 Javascript
详解微信小程序实现WebSocket心跳重连
2018/07/31 Javascript
JavaScript函数IIFE使用详解
2019/10/21 Javascript
vue-cli3.0实现一个多页面应用的历奇经历记录总结
2020/03/16 Javascript
让python json encode datetime类型
2010/12/28 Python
在Python的Django框架中包装视图函数
2015/07/20 Python
Python输出带颜色的字符串实例
2017/10/10 Python
详解Python发送email的三种方式
2018/10/18 Python
python多线程共享变量的使用和效率方法
2019/07/16 Python
详解程序意外中断自动重启shell脚本(以Python为例)
2019/07/26 Python
python实现爱奇艺登陆密码RSA加密的方法示例详解
2020/05/27 Python
Python ADF 单位根检验 如何查看结果的实现
2020/06/03 Python
python使用Word2Vec进行情感分析解析
2020/07/31 Python
GitHub上值得推荐的8个python 项目
2020/10/30 Python
MANGO官方网站:西班牙芒果服装品牌
2017/01/15 全球购物
百联网上商城:i百联
2017/01/28 全球购物
迪拜领先运动补剂零售品牌中文站:Sporter商城
2019/08/20 全球购物
PHP高级工程师面试问题推荐
2013/01/18 面试题
一个大学生十年的职业规划
2014/01/17 职场文书
公司合作意向书
2014/04/01 职场文书
优秀学生干部先进事迹材料
2014/05/26 职场文书
农村党员对照检查材料
2014/09/24 职场文书
五四青年节活动总结
2015/02/10 职场文书
2016大学自主招生推荐信范文
2015/03/23 职场文书
JavaScript执行机制详细介绍
2021/12/06 Javascript
「我的青春恋爱物语果然有问题。-妄言录-」第20卷封面公开
2022/03/21 日漫
Python使用PyYAML库读写yaml文件的方法
2022/04/06 Python