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 相关文章推荐
JoshChen_web格式编码UTF8-无BOM的小细节分析
Aug 16 PHP
php使用websocket示例详解
Mar 12 PHP
C#使用PHP服务端的Web Service通信实例
Apr 08 PHP
PHP微信开发之二维码生成类
Jun 26 PHP
详解WordPress开发中过滤属性以及Sql语句的函数使用
Dec 25 PHP
Zend Framework教程之请求对象的封装Zend_Controller_Request实例详解
Mar 07 PHP
highchart数据源纵轴json内的值必须是int(详解)
Feb 20 PHP
PHP实现基于PDO扩展连接PostgreSQL对象关系数据库示例
Mar 31 PHP
PHP面向对象五大原则之接口隔离原则(ISP)详解
Apr 04 PHP
php微信公众号开发之校园图书馆
Oct 20 PHP
如何在centos8自定义目录安装php7.3
Nov 28 PHP
php使用redis的有序集合zset实现延迟队列应用示例
Feb 20 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 header 跳转
2013/06/17 PHP
理解PHP中的stdClass类
2014/04/18 PHP
laravel学习笔记之模型事件的几种用法示例
2017/08/15 PHP
phpStudy 2016 使用教程详解(支持PHP7)
2017/10/18 PHP
Thinkphp 在api开发中异常返回依然是html的解决方式
2019/10/16 PHP
php的对象传值与引用传值代码实例讲解
2021/02/26 PHP
用JavaScript隐藏控件的方法
2009/09/21 Javascript
js中关于new Object时传参的一些细节分析
2011/03/13 Javascript
JQuery之拖拽插件实现代码
2011/04/14 Javascript
JS操作select下拉框动态变动(创建/删除/获取)
2013/06/02 Javascript
复制js对象方法(详解)
2013/07/08 Javascript
js调用iframe实现打印页面内容的方法
2014/03/04 Javascript
手写的一个兼容各种浏览器的javascript getStyle函数(获取元素的样式)
2014/06/06 Javascript
jquery pagination插件动态分页实例(Bootstrap分页)
2016/12/23 Javascript
JS利用正则表达式实现简单的密码强弱判断实例
2017/06/16 Javascript
React diff算法的实现示例
2018/04/20 Javascript
vue translate peoject实现在线翻译功能【新手必看】
2018/06/07 Javascript
AngularJs返回前一页面时刷新一次前面页面的方法
2018/10/09 Javascript
[04:41]2014DOTA2国际邀请赛 Liquid顺利突围晋级正赛
2014/07/09 DOTA
[51:43]OG vs LGD 2018国际邀请赛淘汰赛BO3 第五场 8.26
2018/08/30 DOTA
css3过渡_动力节点Java学院整理
2017/07/11 HTML / CSS
css3加js做一个简单的3D行星运转效果实例代码
2017/01/18 HTML / CSS
纯css3实现宠物小鸡实例代码
2018/10/08 HTML / CSS
船餐厅和泰晤士河餐饮游轮:Bateaux London
2018/03/19 全球购物
美国嘻哈文化生活方式品牌:GLD
2018/04/15 全球购物
俄罗斯第一家篮球店:StreetBall
2020/07/30 全球购物
一套Delphi的笔试题一
2016/02/14 面试题
2014年教师节演讲稿范文
2014/09/10 职场文书
2014年学校体育工作总结
2014/12/08 职场文书
骨干教师申报材料
2014/12/17 职场文书
餐饮服务食品安全承诺书
2015/04/29 职场文书
2015年暑期社会实践总结
2015/07/13 职场文书
运动会宣传稿50字
2015/07/23 职场文书
导游词之麻姑仙境
2019/11/18 职场文书
java Nio使用NioSocket客户端与服务端交互实现方式
2021/06/15 Java/Android
MySQL 四种连接和多表查询详解
2021/07/16 MySQL