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 相关文章推荐
php empty,isset,is_null判断比较(差异与异同)
Oct 19 PHP
php数组函数序列之ksort()对数组的元素键名进行升序排序,保持索引关系
Nov 02 PHP
第三章 php操作符与控制结构代码
Dec 30 PHP
Session的工作机制详解和安全性问题(PHP实例讲解)
Apr 10 PHP
PHP+jQuery 注册模块的改进(三):更新到Smarty3.1
Oct 14 PHP
PHP读取txt文本文件并分页显示的方法
Mar 11 PHP
PHP传参之传值与传址的区别
Apr 24 PHP
用PHP生成excel文件到指定目录
Jun 22 PHP
CI框架中数据库操作函数$this-&gt;db-&gt;where()相关用法总结
May 17 PHP
Yii2中使用join、joinwith多表关联查询
Jun 30 PHP
PHP基于接口技术实现简单的多态应用完整实例
Apr 26 PHP
PHP-X系列教程之内置函数的使用示例
Oct 16 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
dedecms中常见问题修改方法总结
2007/03/21 PHP
IIS下PHP连接数据库提示mysql undefined function mysql_connect()
2010/06/04 PHP
Zend Framework上传文件重命名的实现方法
2016/11/25 PHP
php将html转为图片的实现方法
2017/05/19 PHP
Laravel 集成 Geetest验证码的方法
2018/05/14 PHP
php + WebUploader实现图片批量上传功能
2019/05/06 PHP
TP5(thinkPHP5)框架使用ajax实现与后台数据交互的方法小结
2020/02/10 PHP
php查看一个变量的占用内存的实例代码
2020/03/29 PHP
HTML5如何适配 iPhone IOS 底部黑条
2021/03/09 HTML / CSS
jquery组件使用中遇到的问题整理及解决
2014/02/21 Javascript
分享两款带遮罩的jQuery弹出框
2015/12/30 Javascript
jQuery中借助deferred来请求及判断AJAX加载的实例讲解
2016/05/24 Javascript
jQuery选择器实例应用
2017/01/05 Javascript
es7学习教程之fetch解决异步嵌套问题的方法示例
2017/07/21 Javascript
使用vue如何构建一个自动建站项目
2018/02/05 Javascript
vue-prop父组件向子组件进行传值的方法
2018/03/01 Javascript
详解原生JS动态添加和删除类
2019/03/26 Javascript
[52:15]2014 DOTA2国际邀请赛中国区预选赛5.21 HGT VS LGD-GAMING
2014/05/23 DOTA
详解 Python中LEGB和闭包及装饰器
2017/08/03 Python
对python中的logger模块全面讲解
2018/04/28 Python
Django model反向关联名称的方法
2018/12/15 Python
python psutil模块使用方法解析
2019/08/01 Python
简单了解python列表和元组的区别
2020/05/14 Python
用HTML5制作一个简单的桌球游戏的教程
2015/05/12 HTML / CSS
Java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?
2012/05/30 面试题
车辆安全检查制度
2014/01/12 职场文书
学校大课间活动方案
2014/01/30 职场文书
共产党员公开承诺书范文
2014/03/28 职场文书
服装设计专业毕业生求职信
2014/04/09 职场文书
2014优秀大学生简历自我评价
2014/09/15 职场文书
大学运动会加油稿200字(5篇)
2014/09/27 职场文书
安全责任书
2015/01/29 职场文书
导游词之山东八仙过海景区
2019/11/11 职场文书
吃通javascript正则表达式
2021/04/21 Javascript
pytorch fine-tune 预训练的模型操作
2021/06/03 Python
解决Swagger2返回map复杂结构不能解析的问题
2021/07/02 Java/Android