Heim > Backend-Entwicklung > PHP-Tutorial > thinkphp微信开发:安全模式讯息加解密

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

WBOY
Freigeben: 2016-06-13 12:27:49
Original
804 Leute haben es durchsucht

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

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

 

                                                                                                                                                                                                                  TRight

分析问题:

          解密微信服务器消息老是不成功,下载下微信公众平台官方给出的解密文件和WechatCrypt.class.php进行比对发现也没有问题。用file_put_contents函数保存下解密后的文件进行分析。发现官方包解密的xml不是标准的xml格式,所以simplexml_load_string函数无法处理。

<span style="color: #008000;">/*</span><span style="color: #008000;">*     * 对密文进行解密     * @param  string $encrypt 密文     * @return string          明文     </span><span style="color: #008000;">*/</span>    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> decrypt(<span style="color: #800080;">$encrypt</span><span style="color: #000000;">){        </span><span style="color: #008000;">//</span><span style="color: #008000;">BASE64解码</span>        <span style="color: #800080;">$encrypt</span> = <span style="color: #008080;">base64_decode</span>(<span style="color: #800080;">$encrypt</span><span style="color: #000000;">);        </span><span style="color: #008000;">//</span><span style="color: #008000;">打开加密算法模块</span>        <span style="color: #800080;">$td</span> = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, ''<span style="color: #000000;">);        </span><span style="color: #008000;">//</span><span style="color: #008000;">初始化加密算法模块</span>        mcrypt_generic_init(<span style="color: #800080;">$td</span>, <span style="color: #800080;">$this</span>->cyptKey, <span style="color: #008080;">substr</span>(<span style="color: #800080;">$this</span>->cyptKey, 0, 16<span style="color: #000000;">));        </span><span style="color: #008000;">//</span><span style="color: #008000;">执行解密</span>        <span style="color: #800080;">$decrypt</span> = mdecrypt_generic(<span style="color: #800080;">$td</span>, <span style="color: #800080;">$encrypt</span><span style="color: #000000;">);               </span><span style="color: #008000;">//</span><span style="color: #008000;">去除PKCS7补位</span>        <span style="color: #800080;">$decrypt</span> = self::PKCS7Decode(<span style="color: #800080;">$decrypt</span>, mcrypt_enc_get_key_size(<span style="color: #800080;">$td</span><span style="color: #000000;">));        </span><span style="color: #008000;">//</span><span style="color: #008000;">关闭加密算法模块</span>        mcrypt_generic_deinit(<span style="color: #800080;">$td</span><span style="color: #000000;">);        mcrypt_module_close(</span><span style="color: #800080;">$td</span><span style="color: #000000;">);        </span><span style="color: #0000ff;">if</span>(<span style="color: #008080;">strlen</span>(<span style="color: #800080;">$decrypt</span>) ){            <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> \<span style="color: #0000ff;">Exception</span>("非法密文字符串!"<span style="color: #000000;">);        }        </span><span style="color: #008000;">//</span><span style="color: #008000;">去除随机字符串</span>        <span style="color: #800080;">$decrypt</span> = <span style="color: #008080;">substr</span>(<span style="color: #800080;">$decrypt</span>, 16<span style="color: #000000;">);        </span><span style="color: #008000;">//</span><span style="color: #008000;">获取网络字节序</span>        <span style="color: #800080;">$size</span> = <span style="color: #008080;">unpack</span>("N", <span style="color: #008080;">substr</span>(<span style="color: #800080;">$decrypt</span>, 0, 4<span style="color: #000000;">));        </span><span style="color: #800080;">$size</span> = <span style="color: #800080;">$size</span>[1<span style="color: #000000;">];        </span><span style="color: #008000;">//</span><span style="color: #008000;">APP_ID</span>        <span style="color: #800080;">$appid</span> = <span style="color: #008080;">substr</span>(<span style="color: #800080;">$decrypt</span>, <span style="color: #800080;">$size</span> + 4<span style="color: #000000;">);        </span><span style="color: #008000;">//</span><span style="color: #008000;">验证APP_ID</span>        <span style="color: #0000ff;">if</span>(<span style="color: #800080;">$appid</span> !== <span style="color: #800080;">$this</span>-><span style="color: #000000;">appId){            </span><span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> \<span style="color: #0000ff;">Exception</span>("非法APP_ID!"<span style="color: #000000;">);        }                </span><span style="color: #008000;">//</span><span style="color: #008000;">明文内容</span>        <span style="color: #800080;">$text</span> = <span style="color: #008080;">substr</span>(<span style="color: #800080;">$decrypt</span>, 4, <span style="color: #800080;">$size</span><span style="color: #000000;">);        </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$text</span><span style="color: #000000;">;    }    </span><span style="color: #008000;">/*</span><span style="color: #008000;">*     * PKCS7填充字符     * @param string  $text 被填充字符     * @param integer $size Block长度     </span><span style="color: #008000;">*/</span>    <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">function</span> PKCS7Encode(<span style="color: #800080;">$text</span>, <span style="color: #800080;">$size</span><span style="color: #000000;">){        </span><span style="color: #008000;">//</span><span style="color: #008000;">字符串长度</span>        <span style="color: #800080;">$str_size</span> = <span style="color: #008080;">strlen</span>(<span style="color: #800080;">$text</span><span style="color: #000000;">);        </span><span style="color: #008000;">//</span><span style="color: #008000;">填充长度</span>        <span style="color: #800080;">$pad_size</span> = <span style="color: #800080;">$size</span> - (<span style="color: #800080;">$str_size</span> % <span style="color: #800080;">$size</span><span style="color: #000000;">);        </span><span style="color: #800080;">$pad_size</span> = <span style="color: #800080;">$pad_size</span> ? : <span style="color: #800080;">$size</span><span style="color: #000000;">;                </span><span style="color: #008000;">//</span><span style="color: #008000;">填充的字符</span>        <span style="color: #800080;">$pad_chr</span> = <span style="color: #008080;">chr</span>(<span style="color: #800080;">$pad_size</span><span style="color: #000000;">);        </span><span style="color: #008000;">//</span><span style="color: #008000;">执行填充</span>        <span style="color: #800080;">$text</span> = <span style="color: #008080;">str_pad</span>(<span style="color: #800080;">$text</span>, <span style="color: #800080;">$str_size</span> + <span style="color: #800080;">$pad_size</span>, <span style="color: #800080;">$pad_chr</span>,<span style="color: #000000;"> STR_PAD_RIGHT);        </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$text</span><span style="color: #000000;">;    }    </span><span style="color: #008000;">/*</span><span style="color: #008000;">*     * 删除PKCS7填充的字符     * @param string  $text 已填充的字符     * @param integer $size Block长度     </span><span style="color: #008000;">*/</span>    <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">function</span> PKCS7Decode(<span style="color: #800080;">$text</span>, <span style="color: #800080;">$size</span><span style="color: #000000;">){        </span><span style="color: #008000;">//</span><span style="color: #008000;">获取补位字符</span>        <span style="color: #800080;">$pad_str</span> = <span style="color: #008080;">ord</span>(<span style="color: #008080;">substr</span>(<span style="color: #800080;">$text</span>, -1<span style="color: #000000;">));        </span><span style="color: #0000ff;">if</span> (<span style="color: #800080;">$pad_str</span> $pad_str > <span style="color: #800080;">$size</span><span style="color: #000000;">) {            </span><span style="color: #800080;">$pad_str</span>= 0<span style="color: #000000;">;        }             </span><span style="color: #0000ff;">return</span> <span style="color: #008080;">substr</span>(<span style="color: #800080;">$text</span>, 0, <span style="color: #008080;">strlen</span>(<span style="color: #800080;">$text</span>) - <span style="color: #800080;">$pad_str</span><span style="color: #000000;">);            }</span>
Nach dem Login kopieren

解决方法:

           输出的xml文件是这样的

<span style="color: #008080;">1</span> <span style="color: #0000ff;"><span style="color: #800000;">xml</span><span style="color: #0000ff;">></span><span style="color: #008080;">2</span> <span style="color: #0000ff;"><span style="color: #800000;">ToUserName</span><span style="color: #0000ff;">></span><span style="color: #0000ff;"><span style="color: #808080;">gh_249aeb986d99</span><span style="color: #0000ff;">]]></span><span style="color: #0000ff;"><span style="color: #800000;">\/ToUserName</span><span style="color: #0000ff;">></span><span style="color: #000000;">\n</span><span style="color: #008080;">3</span> <span style="color: #0000ff;"><span style="color: #800000;">FromUserName</span><span style="color: #0000ff;">></span><span style="color: #0000ff;"><span style="color: #808080;">oopVmxHZaeQkDPsRcbpwXKkH-J2Q</span><span style="color: #0000ff;">]]></span><span style="color: #0000ff;"><span style="color: #800000;">\/FromUserName</span><span style="color: #0000ff;">></span><span style="color: #000000;">\n</span><span style="color: #008080;">4</span> <span style="color: #0000ff;"><span style="color: #800000;">CreateTime</span><span style="color: #0000ff;">></span>1448944621<span style="color: #0000ff;"><span style="color: #800000;">\/CreateTime</span><span style="color: #0000ff;">></span><span style="color: #000000;">\n</span><span style="color: #008080;">5</span> <span style="color: #0000ff;"><span style="color: #800000;">MsgType</span><span style="color: #0000ff;">></span><span style="color: #0000ff;"><span style="color: #808080;">text</span><span style="color: #0000ff;">]]></span><span style="color: #0000ff;"><span style="color: #800000;">\/MsgType</span><span style="color: #0000ff;">></span><span style="color: #000000;">\n</span><span style="color: #008080;">6</span> <span style="color: #0000ff;"><span style="color: #800000;">Content</span><span style="color: #0000ff;">></span><span style="color: #0000ff;"><span style="color: #808080;">\u7ecf\u7406</span><span style="color: #0000ff;">]]></span><span style="color: #0000ff;"><span style="color: #800000;">\/Content</span><span style="color: #0000ff;">></span><span style="color: #000000;">\n</span><span style="color: #008080;">7</span> <span style="color: #0000ff;"><span style="color: #800000;">MsgId</span><span style="color: #0000ff;">></span>6223169761311044588<span style="color: #0000ff;"><span style="color: #800000;">\/MsgId</span><span style="color: #0000ff;">></span><span style="color: #000000;">\n</span><span style="color: #008080;">8</span> <span style="color: #0000ff;"><span style="color: #800000;">\/xml</span><span style="color: #0000ff;">></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>
Nach dem Login kopieren

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

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

<span style="color: #008080;">1</span> <span style="color: #000000;">//明文内容</span><span style="color: #008080;">2</span> <span style="color: #000000;">        $text = substr($decrypt, 4, $size);</span><span style="color: #008080;">3</span> <span style="color: #000000;">//去掉多余的内容</span><span style="color: #008080;">4</span>         $text=str_replace('<span style="color: #0000ff;"><span style="color: #800000;">\/','', $text</span><span style="color: #ff0000;">);      </span><span style="color: #008080;">5</span> <span style="color: #ff0000;">        $text</span><span style="color: #0000ff;">=str_replace('>\n','>', </span><span style="color: #ff0000;">$text);</span><span style="color: #008080;">6</span> <span style="color: #ff0000;">        return $text;</span></span>
Nach dem Login kopieren

 

 

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

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage