Using thinkphp’s official WeChat package, different modes can be used successfully, but the safe mode does not work. Now Record the analysis and solution results.
Analysis of the problem:
Decrypting WeChat server messages is always unsuccessful. Download the official decrypted file provided by the WeChat public platform and compare it with WechatCrypt.class.php and find that there is no problem. Use the file_put_contents function to save the decrypted file for analysis. It was found that the xml decrypted by the official package is not in the standard xml format, so the simplexml_load_string function cannot handle it.
<span>/*</span><span>* * 对密文进行解密 * @param string $encrypt 密文 * @return string 明文 </span><span>*/</span> <span>public</span> <span>function</span> decrypt(<span>$encrypt</span><span>){ </span><span>//</span><span>BASE64解码</span> <span>$encrypt</span> = <span>base64_decode</span>(<span>$encrypt</span><span>); </span><span>//</span><span>打开加密算法模块</span> <span>$td</span> = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, ''<span>); </span><span>//</span><span>初始化加密算法模块</span> mcrypt_generic_init(<span>$td</span>, <span>$this</span>->cyptKey, <span>substr</span>(<span>$this</span>->cyptKey, 0, 16<span>)); </span><span>//</span><span>执行解密</span> <span>$decrypt</span> = mdecrypt_generic(<span>$td</span>, <span>$encrypt</span><span>); </span><span>//</span><span>去除PKCS7补位</span> <span>$decrypt</span> = self::PKCS7Decode(<span>$decrypt</span>, mcrypt_enc_get_key_size(<span>$td</span><span>)); </span><span>//</span><span>关闭加密算法模块</span> mcrypt_generic_deinit(<span>$td</span><span>); mcrypt_module_close(</span><span>$td</span><span>); </span><span>if</span>(<span>strlen</span>(<span>$decrypt</span>) < 16<span>){ </span><span>throw</span> <span>new</span> \<span>Exception</span>("非法密文字符串!"<span>); } </span><span>//</span><span>去除随机字符串</span> <span>$decrypt</span> = <span>substr</span>(<span>$decrypt</span>, 16<span>); </span><span>//</span><span>获取网络字节序</span> <span>$size</span> = <span>unpack</span>("N", <span>substr</span>(<span>$decrypt</span>, 0, 4<span>)); </span><span>$size</span> = <span>$size</span>[1<span>]; </span><span>//</span><span>APP_ID</span> <span>$appid</span> = <span>substr</span>(<span>$decrypt</span>, <span>$size</span> + 4<span>); </span><span>//</span><span>验证APP_ID</span> <span>if</span>(<span>$appid</span> !== <span>$this</span>-><span>appId){ </span><span>throw</span> <span>new</span> \<span>Exception</span>("非法APP_ID!"<span>); } </span><span>//</span><span>明文内容</span> <span>$text</span> = <span>substr</span>(<span>$decrypt</span>, 4, <span>$size</span><span>); </span><span>return</span> <span>$text</span><span>; } </span><span>/*</span><span>* * PKCS7填充字符 * @param string $text 被填充字符 * @param integer $size Block长度 </span><span>*/</span> <span>private</span> <span>static</span> <span>function</span> PKCS7Encode(<span>$text</span>, <span>$size</span><span>){ </span><span>//</span><span>字符串长度</span> <span>$str_size</span> = <span>strlen</span>(<span>$text</span><span>); </span><span>//</span><span>填充长度</span> <span>$pad_size</span> = <span>$size</span> - (<span>$str_size</span> % <span>$size</span><span>); </span><span>$pad_size</span> = <span>$pad_size</span> ? : <span>$size</span><span>; </span><span>//</span><span>填充的字符</span> <span>$pad_chr</span> = <span>chr</span>(<span>$pad_size</span><span>); </span><span>//</span><span>执行填充</span> <span>$text</span> = <span>str_pad</span>(<span>$text</span>, <span>$str_size</span> + <span>$pad_size</span>, <span>$pad_chr</span>,<span> STR_PAD_RIGHT); </span><span>return</span> <span>$text</span><span>; } </span><span>/*</span><span>* * 删除PKCS7填充的字符 * @param string $text 已填充的字符 * @param integer $size Block长度 </span><span>*/</span> <span>private</span> <span>static</span> <span>function</span> PKCS7Decode(<span>$text</span>, <span>$size</span><span>){ </span><span>//</span><span>获取补位字符</span> <span>$pad_str</span> = <span>ord</span>(<span>substr</span>(<span>$text</span>, -1<span>)); </span><span>if</span> (<span>$pad_str</span> < 1 || <span>$pad_str</span> > <span>$size</span><span>) { </span><span>$pad_str</span>= 0<span>; } </span><span>return</span> <span>substr</span>(<span>$text</span>, 0, <span>strlen</span>(<span>$text</span>) - <span>$pad_str</span><span>); }</span>
<span>1</span> <span><</span><span>xml</span><span>></span> <span>2</span> <span><</span><span>ToUserName</span><span>></span><span><![CDATA[</span><span>gh_249aeb986d99</span><span>]]></span><span><</span><span>\/ToUserName</span><span>></span><span>\n </span><span>3</span> <span><</span><span>FromUserName</span><span>></span><span><![CDATA[</span><span>oopVmxHZaeQkDPsRcbpwXKkH-J2Q</span><span>]]></span><span><</span><span>\/FromUserName</span><span>></span><span>\n </span><span>4</span> <span><</span><span>CreateTime</span><span>></span>1448944621<span><</span><span>\/CreateTime</span><span>></span><span>\n </span><span>5</span> <span><</span><span>MsgType</span><span>></span><span><![CDATA[</span><span>text</span><span>]]></span><span><</span><span>\/MsgType</span><span>></span><span>\n </span><span>6</span> <span><</span><span>Content</span><span>></span><span><![CDATA[</span><span>\u7ecf\u7406</span><span>]]></span><span><</span><span>\/Content</span><span>></span><span>\n </span><span>7</span> <span><</span><span>MsgId</span><span>></span>6223169761311044588<span><</span><span>\/MsgId</span><span>></span><span>\n </span><span>8</span> <span><</span><span>\/xml</span><span>></span>
Add
after the output plain text content
<span>1</span> <span>//明文内容 </span><span>2</span> <span> $text = substr($decrypt, 4, $size); </span><span>3</span> <span>//去掉多余的内容 </span><span>4</span> $text=str_replace('<span><</span><span>\/','</', $text</span><span>); </span><span>5</span> <span> $text</span><span>=str_replace('>\n','>', </span><span>$text); </span><span>6</span> <span> return $text;</span>
Safe mode can be used normally.