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 daodb插入、更新与删除数据
Mar 19 PHP
PHP 简单数组排序实现代码
Aug 05 PHP
mysql下创建字段并设置主键的php代码
May 16 PHP
一个基于PDO的数据库操作类
Mar 24 PHP
PHP ? EasyUI DataGrid 资料取的方式介绍
Nov 07 PHP
php xml常用函数的集合(比较详细)
Jun 06 PHP
php+js iframe实现上传头像界面无跳转
Apr 29 PHP
thinkphp在php7环境下提示Cannot use ‘String’ as class name as it is reserved的解决方法
Sep 30 PHP
php实现等比例压缩图片
Jul 26 PHP
laravel利用中间件做防非法登录和权限控制示例
Oct 21 PHP
Laravel相关的一些故障解决
Aug 19 PHP
goto语法在PHP中的使用教程
Sep 17 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
PHP控制网页过期时间的代码
2008/09/28 PHP
phpmyadmin 访问被拒绝的真实原因
2009/06/15 PHP
php date与gmdate的获取日期的区别
2010/02/08 PHP
php 读取文件头判断文件类型的实现代码
2013/08/05 PHP
学习php设计模式 php实现桥梁模式(bridge)
2015/12/07 PHP
如何写php守护进程(Daemon)
2015/12/30 PHP
深入聊聊Array的sort方法的使用技巧.详细点评protype.js中的sortBy方法
2007/04/12 Javascript
jQuery 解析xml文件
2009/08/09 Javascript
替代window.event.srcElement效果的可兼容性的函数
2009/12/18 Javascript
使用 vue.js 构建大型单页应用
2018/02/10 Javascript
vue-router项目实战总结篇
2018/02/11 Javascript
node链接mongodb数据库的方法详解【阿里云服务器环境ubuntu】
2019/03/07 Javascript
微信小程序云开发之云函数详解
2019/05/16 Javascript
ES6 Object属性新的写法实例小结
2019/06/25 Javascript
Vue路由模块化配置的完整步骤
2019/08/14 Javascript
javascript事件监听与事件委托实例详解
2019/08/16 Javascript
利用scrapy将爬到的数据保存到mysql(防止重复)
2018/03/31 Python
基于Python List的赋值方法
2018/06/23 Python
django框架自定义模板标签(template tag)操作示例
2019/06/24 Python
python3 反射的四种基本方法解析
2019/08/26 Python
python批量将excel内容进行翻译写入功能
2019/10/10 Python
Django自关联实现多级联动查询实例
2020/05/19 Python
Django自带用户认证系统使用方法解析
2020/11/12 Python
CSS3实现圆角、阴影、透明效果并兼容各大浏览器
2014/08/08 HTML / CSS
HTML5 input元素类型:email及url介绍
2013/08/13 HTML / CSS
印度尼西亚电子产品购物网站:Kliknklik
2018/06/05 全球购物
介绍一下JNDI的基本概念
2013/07/26 面试题
《独坐敬亭山》教学反思
2014/04/08 职场文书
省级优秀毕业生主要事迹
2014/05/29 职场文书
安全责任书模板
2014/07/22 职场文书
学习型党组织心得体会
2014/09/12 职场文书
2014年个人债务授权委托书范本
2014/09/22 职场文书
2014年档案管理工作总结
2014/11/17 职场文书
道德模范事迹材料
2014/12/20 职场文书
如何做好工作总结!
2019/04/10 职场文书
Spring依赖注入多种类型数据的示例代码
2022/03/31 Java/Android