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 date与gmdate的获取日期的区别
Feb 08 PHP
PHP乱码问题,UTF-8乱码常见问题小结
Apr 09 PHP
phpstorm编辑器乱码问题解决
Dec 01 PHP
PHP模块memcached使用指南
Dec 08 PHP
php文件夹的创建与删除方法
Jan 24 PHP
PHP简单选择排序算法实例
Jan 26 PHP
thinkphp如何获取客户端IP
Nov 03 PHP
PHP 获取指定地区的天气实例代码
Feb 08 PHP
Yii2 加载css、js 载静态资源的方法
Mar 10 PHP
一个非常实用的php文件上传类
Jul 04 PHP
laravel自定义分页效果
Jul 23 PHP
discuz论坛更换域名,详细文件修改步骤
Dec 09 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的无限分类实现想法~
2007/01/02 PHP
PHP Warning: PHP Startup: Unable to load dynamic library \ D:/php5/ext/php_mysqli.dll\
2012/06/17 PHP
PHP以mysqli方式连接类完整代码实例
2014/07/15 PHP
PHP的PDO预处理语句与存储过程
2019/01/27 PHP
JavaScript高级程序设计
2006/12/29 Javascript
JQuery文本框高亮显示插件代码
2011/04/02 Javascript
js实现翻页后保持checkbox选中状态的实现方法
2012/11/03 Javascript
js 窗口抖动示例
2013/09/04 Javascript
如何利用JS通过身份证号获取当事人的生日、年龄、性别
2016/01/22 Javascript
浅谈JSON.stringify()和JOSN.parse()方法的不同
2016/08/29 Javascript
node实现简单的反向代理服务器
2017/07/26 Javascript
原生JS实现日历组件的示例代码
2017/09/22 Javascript
axios使用拦截器统一处理所有的http请求的方法
2018/11/02 Javascript
详解jQuery设置内容和属性
2019/04/11 jQuery
js实现web调用摄像头 js截取视频画面
2019/04/21 Javascript
python解析基于xml格式的日志文件
2017/02/25 Python
django 开发忘记密码通过邮箱找回功能示例
2018/04/17 Python
使用Python的toolz库开始函数式编程的方法
2018/11/15 Python
python 利用文件锁单例执行脚本的方法
2019/02/19 Python
python创造虚拟环境方法总结
2019/03/04 Python
Python with用法:自动关闭文件进程
2019/07/10 Python
python+Django实现防止SQL注入的办法
2019/10/31 Python
Python中低维数组填充高维数组的实现
2019/12/02 Python
python使用协程实现并发操作的方法详解
2019/12/27 Python
pytorch梯度剪裁方式
2020/02/04 Python
对python中各个response的使用说明
2020/03/28 Python
Python浮点型(float)运算结果不正确的解决方案
2020/09/22 Python
墨西哥网上超市:Superama
2018/07/10 全球购物
美国单身专业人士在线约会网站:EliteSingles
2019/03/19 全球购物
启动一个线程是用run()还是start()
2016/12/25 面试题
文秘专业自荐信
2013/10/14 职场文书
交通安全教育制度
2014/02/02 职场文书
员工激励培训演讲稿
2014/09/16 职场文书
2015领导干部廉洁自律工作总结
2015/07/23 职场文书
《七律·长征》教学反思
2016/02/16 职场文书
Java存储没有重复元素的数组
2022/04/29 Java/Android