thinkphp微信开之安全模式消息加密解密不成功的解决办法


Posted in PHP onDecember 02, 2015

 ThinkPHP框架是国内比较流行的PHP框架之一,虽然跟国外的那些框架没法比,但优点在于,恩,中文手册很全面,在此不多说了。

使用thinkphp官方的WeChat包,使用不同模式可以成功,但是安全模式就是不行,现将分析解决结果做下记录。

 分析问题:

          解密微信服务器消息老是不成功,下载下微信公众平台官方给出的解密文件和WechatCrypt.class.php进行比对发现也没有问题。用file_put_contents函数保存下解密后的文件进行分析。发现官方包解密的xml不是标准的xml格式,所以simplexml_load_string函数无法处理。

/**
   * 对密文进行解密
   * @param string $encrypt 密文
   * @return string     明文
   */
  public function decrypt($encrypt){
    //BASE64解码
    $encrypt = base64_decode($encrypt);
    //打开加密算法模块
    $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
    //初始化加密算法模块
    mcrypt_generic_init($td, $this->cyptKey, substr($this->cyptKey, 0, 16));
    //执行解密
    $decrypt = mdecrypt_generic($td, $encrypt);
    //去除PKCS7补位
    $decrypt = self::PKCS7Decode($decrypt, mcrypt_enc_get_key_size($td));
    //关闭加密算法模块
    mcrypt_generic_deinit($td);
    mcrypt_module_close($td);
    if(strlen($decrypt) < 16){
      throw new \Exception("非法密文字符串!");
    }
    //去除随机字符串
    $decrypt = substr($decrypt, 16);
    //获取网络字节序
    $size = unpack("N", substr($decrypt, 0, 4));
    $size = $size[1];
    //APP_ID
    $appid = substr($decrypt, $size + 4);
    //验证APP_ID
    if($appid !== $this->appId){
      throw new \Exception("非法APP_ID!");
    }
    //明文内容
    $text = substr($decrypt, 4, $size);
    return $text;
  }
  /**
   * PKCS7填充字符
   * @param string $text 被填充字符
   * @param integer $size Block长度
   */
  private static function PKCS7Encode($text, $size){
    //字符串长度
    $str_size = strlen($text);
    //填充长度
    $pad_size = $size - ($str_size % $size);
    $pad_size = $pad_size ? : $size;
    //填充的字符
    $pad_chr = chr($pad_size);
    //执行填充
    $text = str_pad($text, $str_size + $pad_size, $pad_chr, STR_PAD_RIGHT);
    return $text;
  }
  /**
   * 删除PKCS7填充的字符
   * @param string $text 已填充的字符
   * @param integer $size Block长度
   */
  private static function PKCS7Decode($text, $size){
    //获取补位字符
    $pad_str = ord(substr($text, -1));
    if ($pad_str < 1 || $pad_str > $size) {
      $pad_str= 0;
    } 
      return substr($text, 0, strlen($text) - $pad_str);
  }

解决方法:

          输出的xml文件是这样的

<xml>
 <ToUserName><![CDATA[gh_aebd]]><\/ToUserName>\n
 <FromUserName><![CDATA[oopVmxHZaeQkDPsRcbpwXKkH-JQ]]><\/FromUserName>\n
 <CreateTime><\/CreateTime>\n
 <MsgType><![CDATA[text]]><\/MsgType>\n
 <Content><![CDATA[\uecf\u]]><\/Content>\n
 <MsgId><\/MsgId>\n
 <\/xml>

       所以需要进行处理才能让simplexml_load_string处理

在输出的明文内容后面加上

//明文内容
     $text = substr($decrypt, , $size);
 //去掉多余的内容
     $text=str_replace('<\/','</', $text);   
     $text=str_replace('>\n','>', $text);
     return $text;

安全模式就能正常使用了。

以上内容是小编给大家介绍的关于thinkphp微信开之安全模式消息加密解密不成功的解决办法,希望大家喜欢。

PHP 相关文章推荐
杏林同学录(九)
Oct 09 PHP
echo(),print(),print_r()之间的区别?
Nov 19 PHP
php简单封装了一些常用JS操作
Feb 25 PHP
PHP程序开发范例学习之表单 获取文本框的值
Aug 08 PHP
PHP往XML中添加节点的方法
Mar 12 PHP
php实现向javascript传递数组的方法
Jul 27 PHP
如何把php5.3版本升级到php5.4或者php5.5
Jul 31 PHP
php文档工具PHP Documentor安装与使用方法
Jan 25 PHP
php使用PDO执行SQL语句的方法分析
Feb 16 PHP
php+mysql+jquery实现简易的检索自动补全提示功能
Apr 15 PHP
yii2项目实战之restful api授权验证详解
May 20 PHP
ThinkPHP3.2.3框架实现的空模块、空控制器、空操作,跳转到错误404页面图文详解
Apr 03 PHP
PHP接收json 并将接收数据插入数据库的实现代码
Dec 01 #PHP
实例讲解yii2.0在php命令行中运行的步骤
Dec 01 #PHP
PHP简单的MVC框架实现方法
Dec 01 #PHP
分享PHP源码批量抓取远程网页图片并保存到本地的实现方法
Dec 01 #PHP
基于php实现七牛抓取远程图片
Dec 01 #PHP
使用Huagepage和PGO来提升PHP7的执行性能
Nov 30 #PHP
深入解析PHP中foreach语句控制数组循环的用法
Nov 30 #PHP
You might like
PHPMYADMIN 简明安装教程 推荐
2010/03/07 PHP
PHP逐行输出(ob_flush与flush的组合)
2012/02/04 PHP
探讨Hessian在PHP中的使用分析
2013/06/13 PHP
PHP全功能无变形图片裁剪操作类与用法示例
2017/01/10 PHP
PHP 返回数组后处理方法(开户成功后弹窗提示)
2017/07/03 PHP
jquery中实现标签切换效果的代码
2011/03/01 Javascript
基于jQuery的简单的列表导航菜单
2011/03/02 Javascript
javascript中Math.random()使用详解
2015/04/15 Javascript
JavaScript中的this到底是什么(一)
2015/12/09 Javascript
理解JavaScript原型链
2016/10/25 Javascript
8 行 Node.js 代码实现代理服务器
2016/12/05 Javascript
Vue.Draggable实现拖拽效果
2020/07/29 Javascript
简单的Vue异步组件实例Demo
2017/12/27 Javascript
解决Vue 项目打包后favicon无法正常显示的问题
2018/09/01 Javascript
iview Upload组件多个文件上传的示例代码
2018/09/30 Javascript
vue路由 遍历生成复数router-link的例子
2019/10/30 Javascript
解决vue路由name同名,路由重复的问题
2020/08/05 Javascript
python创建和使用字典实例详解
2013/11/01 Python
Python利用Nagios增加微信报警通知的功能
2016/02/18 Python
django 2.0更新的10条注意事项总结
2018/01/05 Python
Python向excel中写入数据的方法
2019/05/05 Python
python网络应用开发知识点浅析
2019/05/28 Python
python打包exe开机自动启动的实例(windows)
2019/06/28 Python
Python对列表的操作知识点详解
2019/08/20 Python
Python3 中作为一等对象的函数解析
2019/12/11 Python
Python3爬虫mitmproxy的安装步骤
2020/07/29 Python
基于Python爬取京东双十一商品价格曲线
2020/10/23 Python
银行出纳岗位职责
2013/11/25 职场文书
英语商务邀请函范文
2014/01/16 职场文书
北京奥运会主题口号
2014/06/13 职场文书
安全保卫工作竞聘材料
2014/08/25 职场文书
党员反对四风问题思想汇报
2014/09/12 职场文书
幼师自荐信范文
2015/03/06 职场文书
2015年办公室文员工作总结
2015/04/24 职场文书
小兵张嘎观后感300字
2015/06/03 职场文书
ajax请求前端跨域问题原因及解决方案
2021/10/16 Javascript