ThinkPHP框架是國內比較流行的PHP框架之一,雖然跟國外的那些框架沒法比,但優點在于,恩,中文手冊很全面,在此不多說了。
使用thinkphp官方的WeChat包,使用不同模式可以成功,但是安全模式就是不行,現將分析解決結果做下記錄。
分析問題:
解密微信服務器消息老是不成功,下載下微信公眾平臺官方給出的解密文件和WechatCrypt.class.php進行比對發現也沒有問題。用file_put_contents函數保存下解密后的文件進行分析。發現官方包解密的xml不是標準的xml格式,所以simplexml_load_string函數無法處理。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
/** * 對密文進行解密 * @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
2
3
4
5
6
7
8
|
<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處理
在輸出的明文內容后面加上
1
2
3
4
5
6
|
//明文內容 $text = substr ( $decrypt , , $size ); //去掉多余的內容 $text = str_replace ( '<\/' , '</' , $text ); $text = str_replace ( '>\n' , '>' , $text ); return $text ; |
安全模式就能正常使用了。
以上內容是小編給大家介紹的關于thinkphp微信開之安全模式消息加密解密不成功的解決辦法,希望大家喜歡。