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 相关文章推荐
如何给phpadmin一个保护
Oct 09 PHP
用PHP实现图象锐化代码
Jun 14 PHP
yii实现CheckBox复选框在同一行显示的方法
Dec 03 PHP
PHP PDO fetch 模式各种参数的输出结果一览
Jan 07 PHP
php中动态调用函数的方法
Mar 16 PHP
一个简单至极的PHP缓存类代码
Oct 23 PHP
Yii实现的多级联动下拉菜单
Jul 13 PHP
PHP实现随机生成水印图片功能
Mar 22 PHP
详解PHP5.6.30与Apache2.4.x配置
Jun 02 PHP
phpstudy的php版本自由修改的方法
Oct 18 PHP
PHP实现基于PDO扩展连接PostgreSQL对象关系数据库示例
Mar 31 PHP
php策略模式简单示例分析【区别于工厂模式】
Sep 25 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
真正根据utf8编码的规律来进行截取字符串的函数(utf8版sub_str )
2012/10/24 PHP
php正确输出json数据的实例讲解
2018/08/21 PHP
使用PHP反射机制来构造&quot;CREATE TABLE&quot;的sql语句
2019/03/21 PHP
thinkphp5.1框架中容器(Container)和门面(Facade)的实现方法分析
2019/08/05 PHP
背景音乐每次刷新都可以自动更换
2007/02/01 Javascript
需要做特殊处理的DOM元素属性的访问
2010/11/05 Javascript
jquery中ajax学习笔记一
2011/10/16 Javascript
jQuery获取Select选择的Text和Value(详细汇总)
2013/01/25 Javascript
jquery在项目中做复选框时遇到的一些问题笔记
2013/11/17 Javascript
基于JQuery实现的图片自动进行缩放和裁剪处理
2014/01/31 Javascript
jQuery中prepend()方法用法实例
2014/12/25 Javascript
jQuery qrcode生成二维码的方法
2016/04/03 Javascript
AngularJs Forms详解及简单示例
2016/09/01 Javascript
Angular.js中$resource高大上的数据交互详解
2017/07/30 Javascript
基于Vue实现支持按周切换的日历
2020/09/24 Javascript
使用vue实现grid-layout功能实例代码
2018/01/05 Javascript
Swiper 4.x 使用方法(移动端网站的内容触摸滑动)
2018/05/17 Javascript
Node.js笔记之process模块解读
2018/05/31 Javascript
vue+element-ui动态生成多级表头的方法
2018/08/28 Javascript
vue cli3.0结合echarts3.0与地图的使用方法示例
2019/03/26 Javascript
Vue基础配置讲解
2019/11/29 Javascript
[01:48]完美圣典齐天大圣至宝宣传片
2016/12/17 DOTA
Python中实现远程调用(RPC、RMI)简单例子
2014/04/28 Python
python装饰器初探(推荐)
2016/07/21 Python
pandas计算最大连续间隔的方法
2019/07/04 Python
python使用装饰器作日志处理的方法
2019/07/11 Python
python函数装饰器之带参数的函数和带参数的装饰器用法示例
2019/11/06 Python
python如何实现复制目录到指定目录
2020/02/13 Python
加拿大休闲和工业服装和鞋类零售商:L’Équipeur
2018/01/12 全球购物
介绍一下Mysql的存储引擎
2015/02/12 面试题
兼职业务员岗位职责
2014/01/01 职场文书
工作证明范本(2篇)
2014/09/14 职场文书
学校运动会通讯稿
2015/07/18 职场文书
小学英语新课改心得体会
2016/01/22 职场文书
pytorch实现线性回归以及多元回归
2021/04/11 Python
Jupyter notebook 输出部分显示不全的解决方案
2021/04/24 Python