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应用程序来获取Web服务器的状态信息
Oct 09 PHP
解析PayPal支付接口的PHP开发方式
Nov 28 PHP
smarty获得当前url的方法分享
Feb 14 PHP
Codeigniter注册登录代码示例
Jun 12 PHP
ThinkPHP3.1新特性之对分组支持的改进与完善概述
Jun 19 PHP
thinkPHP实现瀑布流的方法
Nov 29 PHP
PHP嵌套输出缓冲代码实例
May 12 PHP
学习php设计模式 php实现状态模式
Dec 07 PHP
php读取txt文件并将数据插入到数据库
Feb 23 PHP
详解PHP序列化和反序列化原理
Jan 15 PHP
php把字符串指定字符分割成数组的方法
Mar 12 PHP
PHP递归遍历文件夹去除注释并压缩php源代码的方法示例
May 23 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
Discuz 模板语句分析及知识技巧
2009/08/21 PHP
PHP中使用imagick实现把PDF转成图片
2015/01/26 PHP
php session的应用详细介绍
2017/03/22 PHP
JS+PHP实现用户输入数字后显示最大的值及所在位置
2017/06/19 PHP
jQuery Ajax使用 全解析
2010/12/15 Javascript
利用javascript数组长度循环数组内所有元素
2013/12/27 Javascript
Javascript 按位与赋值运算符 (&amp;=)使用介绍
2014/02/04 Javascript
轻松创建nodejs服务器(6):作出响应
2014/12/18 NodeJs
如何消除inline-block属性带来的标签间间隙
2016/03/31 Javascript
el表达式 写入bootstrap表格数据页面的实例代码
2017/01/11 Javascript
深入理解React Native原生模块与JS模块通信的几种方式
2017/07/24 Javascript
使用proxy实现一个更优雅的vue【推荐】
2018/06/19 Javascript
Vue slot用法(小结)
2018/10/22 Javascript
原生JS检测CSS3动画是否结束的方法详解
2019/01/27 Javascript
js实现文字头像的生成代码
2020/03/07 Javascript
[01:02:48]2018DOTA2亚洲邀请赛 4.1 小组赛 A组 LGD vs OG
2018/04/02 DOTA
Python中编写ORM框架的入门指引
2015/04/29 Python
Python解析json文件相关知识学习
2016/03/01 Python
Python内置函数 next的具体使用方法
2017/11/24 Python
如何在python字符串中输入纯粹的{}
2018/08/22 Python
python_opencv用线段画封闭矩形的实例
2018/12/05 Python
PyQt4编程之让状态栏显示信息的方法
2019/06/18 Python
Python依赖包整体迁移方法详解
2019/08/15 Python
Python中的单下划线和双下划线使用场景详解
2019/09/09 Python
Python3中的tuple函数知识点讲解
2021/01/03 Python
YSL圣罗兰美妆英国官网:Yves Saint Laurent Beauty UK
2019/08/03 全球购物
传播学毕业生求职信
2013/10/11 职场文书
运动会广播稿30字
2014/01/21 职场文书
乡镇干部十八大感言
2014/02/17 职场文书
村级个人对照检查材料
2014/08/22 职场文书
元宵节寄语大全
2015/02/27 职场文书
演讲开场白和结束语
2015/05/29 职场文书
信仰纪录片观后感
2015/06/08 职场文书
oracle表分区的概念及操作
2021/04/24 Oracle
Python字典和列表性能之间的比较
2021/06/07 Python
基于angular实现树形二级表格
2021/10/16 Javascript