转载

thinkphp微信开发:安全模式消息加解密

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

TRight

分析问题:

解密微信服务器消息老是不成功,下载下微信公众平台官方给出的解密文件和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文件是这样的

 1 <xml> 2 <ToUserName><![CDATA[gh_249aeb986d99]]><//ToUserName>/n 3 <FromUserName><![CDATA[oopVmxHZaeQkDPsRcbpwXKkH-J2Q]]><//FromUserName>/n 4 <CreateTime>1448944621<//CreateTime>/n 5 <MsgType><![CDATA[text]]><//MsgType>/n 6 <Content><![CDATA[/u7ecf/u7406]]><//Content>/n 7 <MsgId>6223169761311044588<//MsgId>/n 8 <//xml> 

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

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

 1 //明文内容 2         $text = substr($decrypt, 4, $size); 3 //去掉多余的内容 4         $text=str_replace('<//','</', $text);       5         $text=str_replace('>/n','>', $text); 6         return $text; 

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

正文到此结束
Loading...