微信公众号开发教程[005]-消息管理-消息加解密

时间:2016-07-13 17:24:12   收藏:0   阅读:1179

一.配置公众号消息加解密方式

        在公众号官方管理后台->开发->基本配置->修改配置上有3种方式,如下:

技术分享

其中,EncodingAESKey可以随机生成.

加解密方式说明:

1).明文模式:微信服务器向公众号服务器(即我们要处理的http://szuzsq.tunnel.qydev.com/weixin/index.php)发送的xml结构是原始的,没有加密.如下:

<xml>
	<ToUserName><![CDATA[gh_733c42e0aee9]]></ToUserName>
	<FromUserName><![CDATA[oIaodvwZe03Amjb8_jQ0ZHGmr-4w]]></FromUserName>
	<CreateTime>1468291653</CreateTime>
	<MsgType><![CDATA[text]]></MsgType>
	<Content><![CDATA[i love you]]></Content>
	<MsgId>6306264631030309910</MsgId>
</xml>

而公众号服务器向微信服务器回复的xml结构也是原始的,没有加密.如下:

<xml>
	<ToUserName><![CDATA[oIaodvwZe03Amjb8_jQ0ZHGmr-4w]]></ToUserName>
	<FromUserName><![CDATA[gh_733c42e0aee9]]></FromUserName>
	<CreateTime>12345678</CreateTime>
	<MsgType><![CDATA[text]]></MsgType>
	<Content><![CDATA[你好]]></Content>
</xml>


2).安全模式:微信服务器向公众号服务器发送的xml结构是加密之后的,如下:

<xml>
	<ToUserName><![CDATA[gh_733c42e0aee9]]></ToUserName>
	<Encrypt><![CDATA[5iQIChI9SHJ8AygPRlQXg0TjENPp/+gMsL8QWceqRXbmZa9tfwft9JtVMhsd6acMJjq7s/gi6E/dLoaJ5optAJ3ixUoHlsJSiryZC/wkFZkY4++HQEr9sj0wHbsT9UbbW/TfXY0t5pQtM62hQKHO/AUFHiXAJ31kQrcGY4QZHyJjQDS6bchvufhOnm8paDMak3HeTf0vMBzkSZcl78V23uq8wvV1rBx4K9uzPz6AZmfV2rLbaA5u/fsQFcntl8aDK19PZfZreawt0et3AXv1DgFZEciC8vlCxwta6mjuAEIdL81t4mfa8V28iD8ul+AjWEMKcHszBQqQUkG3BTItB/8o+8h6PLYD+ZsHEUBbPttRhrlo+UlfXTehtGPVnd97GZ72ImWXb5wIadKcGSgXzvRRkVv1zav3CTjRRZH5k8kLqIxso9VmjD4Un+IF8vKaJqAu0irYWFMWYIhQZZ9CQQ==]]></Encrypt>
</xml>


而公众号服务器向微信服务器回复的xml结构也是加密之后的.如下:

<xml>
	<Encrypt><![CDATA[lSK3AQg4RCd3GvUpEVQiZSxBWpAgH3MJjoZIGGjd0rcO14H7JasE2O8bzA/0PusNfKuxMmcCsTq3vHlbrdvALSioQKlpl/QrNH15kelS0bG12UMJhxs1CDa+ES9IuZ4wR7Ra/Oa3kCUh9x0RKdxkAWa0+jgT3bOD0OESMWp8Iynx11QiMBSMzAiEneLUCrszUdV6eBUQvdLTXkrRWYWHdMjgbvb8psc3NyxqB7N0GOG6i7ibk/Zd1s8nsDrYYDFI/BDFgl/wOEBSFC5rWgsgCdhuUEDcnU3N1eb/veL+TJ7zDAImUUPMY/auhm7mBVQcWjpCXutIo03esQJaSGiDxfj4VVBoZslPQc3gUKzm1I4QzCVU27J8/mx41I6Zc54k]]></Encrypt>
	<MsgSignature><![CDATA[5b9bff5f6dd7075d4ec2f4bca880d8ada48c6c7d]]></MsgSignature>
	<TimeStamp>1468291653</TimeStamp>
	<Nonce><![CDATA[1528778891]]></Nonce>
</xml>

3).兼容模式:微信服务器向公众号服务器发送的xml结构即有原始的,也有加密之后的,如下:

<xml>
	<ToUserName><![CDATA[gh_733c42e0aee9]]></ToUserName>
	<FromUserName><![CDATA[oIaodvwZe03Amjb8_jQ0ZHGmr-4w]]></FromUserName>
	<CreateTime>1468291484</CreateTime>
	<MsgType><![CDATA[text]]></MsgType>
	<Content><![CDATA[i love you]]></Content>
	<MsgId>6306263905180836845</MsgId>
	<Encrypt><![CDATA[Kd1lnxCrEr4L3qT4De7Rp2nUgbnYj8M http:// <span style="font-family: Arial, Helvetica, sans-serif;">RpdCc4uTCwMMPkcSQ8KJmlx6rFnQPGh6gBqVaQJ20kXNKCYDQGQ1fur4Pbgydet8cDB+cvYitI/aRHo2KrVbXuJyiyuMuWw1zYWaeYmRCKN3+xyCtmtvPDBTW5PIJ7ZnUX0yGyp3J0oOjIJfULoVPqkUDY4W+Vdh0ZTR9eE7o0u9ioVUd+m5W72jsP61A7mivYCZTolCHWMFdhfoSQlxXm8tnTO1gu3v+vzTUCdWuZhpJNuD6X/Ab+vcgKSdopjlMKze8bUUw9CyT/YwEhj6CJRF46LkasUGC/i5wC7ABbTvZpGpMkuylF9pEY0E6PW+PwECsmY/aEcIp1CcsveddVJUeW9flOqgaDOiRvGyuwVMDTJo9inBuZpCRCGDUKpflBlUoD8nMbZzBxxVkUySjvmdj4Pa2V7gN2jRqtfmMtu9FzFcOyKUL/w==]]></Encrypt></span>
</xml>


而公众号服务器向微信服务器回复的xml结构,则和安全模式下的回复是一样的.如下:

<xml>
	<Encrypt><![CDATA[lSK3AQg4RCd3GvUpEVQiZSxBWpAgH3MJjoZIGGjd0rcO14H7JasE2O8bzA/0PusNfKuxMmcCsTq3vHlbrdvALSioQKlpl/QrNH15kelS0bG12UMJhxs1CDa+ES9IuZ4wR7Ra/Oa3kCUh9x0RKdxkAWa0+jgT3bOD0OESMWp8Iynx11QiMBSMzAiEneLUCrszUdV6eBUQvdLTXkrRWYWHdMjgbvb8psc3NyxqB7N0GOG6i7ibk/Zd1s8nsDrYYDFI/BDFgl/wOEBSFC5rWgsgCdhuUEDcnU3N1eb/veL+TJ7zDAImUUPMY/auhm7mBVQcWjpCXutIo03esQJaSGiDxfj4VVBoZslPQc3gUKzm1I4QzCVU27J8/mx41I6Zc54k]]></Encrypt>
	<MsgSignature><![CDATA[5b9bff5f6dd7075d4ec2f4bca880d8ada48c6c7d]]></MsgSignature>
	<TimeStamp>1468291653</TimeStamp>
	<Nonce><![CDATA[1528778891]]></Nonce>
</xml>


二.微信公众号加解密过程

        写之前要重头吐槽一下,微信官方文档有2个地方https://mp.weixin.qq.com/wikihttp://mp.weixin.qq.com/wiki/home,这2个地方应该是1份新的,1份旧的.但是,我从微信公众号官方后台管理->开发->开发者工具->开发者文档,进入的是第1个地方,按理说应该是新的才对.但是在消息管理->发送消息-被动回复时加解密,这章节上,有一段话:"请开发者查看接入指引和开发者FAQ来接入消息体签名及加解密功能:接入指引,开发者FAQ,若关注技术实现,可查看技术方案:技术方案"在这段话里面,我怎么都找不着接入指引和开发者FAQ这些相关内容.后来,不记得如何,第2个地方,同样地方的同样一句话:"请开发者查看接入指引和开发者FAQ来接入消息体签名及加解密功能:接入指引开发者FAQ,若关注技术实现,可查看技术方案:技术方案"接入指引开发者FAQ技术方案这几处,是有链接的!!!!!!!这里再次鄙视下微信的文档人员!!!!!!!!.

        好了,大家去围观接入指引,里面提到在安全和兼容模式下,微信服务器向公众号服务器转发消息的url上,会添加signature,timestamp,nonce,encrypt_type,msg_signature(注意signature和msg_signature不同)参数.例如:

http://szuzsq.tunnel.qydev.com/weixin/index.php?signature=35703636de2f9df2a77a662b68e521ce17c34db4&timestamp=1468291653&nonce=1528778891&encrypt_type=aes&msg_signature=59e47c61f82b1ac655ea94a9ad214656f573ba5b

        下载微信官方给出的示例代码: http://mp.weixin.qq.com/wiki/static/assets/a5a22f38cb60228cb32ab61d9e4c414b.zip,里面有C++、php、Java、Python和C#版本,我们只取用到的几个文件:errorCode.php,pkcs7Encoder.php,sha1.php,wxBizMsgCrypt.php,xmlparse.php,其中wxBizMsgCrypt.php实现了微信消息加解密的业务逻辑.

1).解密微信服务器向公众号服务器发送的xml.

<?php
	$errCode = $pc->decryptMsg($msg_signature, $timestamp, $nonce, $postStr, $decryptMsg);
?>

2).加密公众号服务器向微信服务器回复的xml.

<?php
	$errCode = $pc->encryptMsg($responseStr, $timestamp, $nonce, $encryptMsg);
?>

其中,$timestamp, $nonce即可以使用微信服务器在url中传进来的,也可以使用自己生成的.


三.完整示例

我的项目目录如下:

技术分享

源文件如下:

<?php
//文件名: http://szuzsq.tunnel.qydev.com/weixin/index.php

require_once('aes/wxBizMsgCrypt.php');

define("TOKEN", "weixin");
define("AppID", "wxc5bc41cb7c73814f");
define("EncodingAESKey", "r0TTQS2o4xxlJcMjCs33leS56rpNJOi12QRldiXS5Lv");

$wechatObj = new wechatCallbackapiTest();
$wechatObj->responseMsg();

class wechatCallbackapiTest {
	public function responseMsg() {
		//微信服务器向公众号服务器发送xml
		$timestamp = $_GET['timestamp'];
		$nonce = $_GET["nonce"];
		$msg_signature = $_GET['msg_signature'];
		$encrypt_type = $_GET['encrypt_type'];
		$postStr = file_get_contents('php://input'); //$GLOBALS["HTTP_RAW_POST_DATA"];

		$pc = new WXBizMsgCrypt(TOKEN, EncodingAESKey, AppID);
		$decryptMsg = ""; //解密后的原文
		$errCode = $pc->decryptMsg($msg_signature, $timestamp, $nonce, $postStr, $decryptMsg);
		error_log("**********************解密**********************\r\ntimestamp:$timestamp\r\nnonce:$nonce\r\nmsg_signature:$msg_signature\r\nencrypt_type:$encrypt_type\r\npostStr:$postStr\r\nerrCode:$errCode\r\ndecryptMsg:$decryptMsg\r\n\r\n", 3, "err.log");

		//公众号服务器向微信服务器回复xml
		$responseStr = "<xml><ToUserName><![CDATA[oIaodvwZe03Amjb8_jQ0ZHGmr-4w]]></ToUserName><FromUserName><![CDATA[gh_733c42e0aee9]]></FromUserName><CreateTime>12345678</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[你好]]></Content></xml>";
		$encryptMsg = ''; //加密后的密文
		$errCode = $pc->encryptMsg($responseStr, $timestamp, $nonce, $encryptMsg);
		error_log("**********************加密**********************\r\nresponseStr:$responseStr\r\nerrCode:$errCode\r\nencryptMsg:$encryptMsg", 3, "err.log");
		echo $encryptMsg;
	}
}
?>

效果如下:

技术分享


代码中2处使用error_log打印出来的内容(为了好看,我后期手动排了下版),如下:

**********************解密**********************
timestamp:1468298136
nonce:1156171062
msg_signature:5d7ad0fe355e800ab05092e62489469e27347bb6
encrypt_type:aes
postStr:
<xml>
	<ToUserName><![CDATA[gh_733c42e0aee9]]></ToUserName>
	<Encrypt><![CDATA[sI7OWIRI1LWe0OSH3aJbg1mIcirMiMQ7Seq8udJ0OAhrIVPKDqX2cf3tD9BPtyEgGIbQcnWIoJ6/JWjRuMSPjEcUgmpSZG1lAFb1YArPXwY2HIoi/n1mPK3E2Mntt55Y2Xp3/GlxuJxH/eg1rdad/98UfBiB5pJcmSM0odJJ+jQ1/ufIAn7fBFWwGpMeEOGtpX7mpMzVMxr5Y3qrNIIT6htnjW2nlwPFatGccHo0ne6BsRDzitLVKKOVUyIRLLcJopLb03GdAQPD3wVvUNtOKxlgvPt0gta09Z5AT6axqyBqB5Po+0TF4gNb8Q3eFJAZkl0fnzCQxnMZytf2NZ9mQjAf1lsTQfc68mCdyJ+y1g4pANvidZYpOKnfl1zI1edbIHKsdKhzWP+LX7neJtL7PNpj6Dzgm6og+z//NYR4JbiMv3DTizGywFbf112yoCiZu/ogeLbarav/5brdsbDZRA==]]></Encrypt>
</xml>

errCode:0
decryptMsg:
<xml>
	<ToUserName><![CDATA[gh_733c42e0aee9]]></ToUserName>
	<FromUserName><![CDATA[oIaodvwZe03Amjb8_jQ0ZHGmr-4w]]></FromUserName>
	<CreateTime>1468298136</CreateTime>
	<MsgType><![CDATA[text]]></MsgType>
	<Content><![CDATA[i love you]]></Content>
	<MsgId>6306292475303292097</MsgId>
</xml>

**********************加密**********************
responseStr:
<xml>
	<ToUserName><![CDATA[oIaodvwZe03Amjb8_jQ0ZHGmr-4w]]></ToUserName>
	<FromUserName><![CDATA[gh_733c42e0aee9]]></FromUserName>
	<CreateTime>12345678</CreateTime>
	<MsgType><![CDATA[text]]></MsgType>
	<Content><![CDATA[你好]]></Content>
</xml>
errCode:0
encryptMsg:
<xml>
	<Encrypt><![CDATA[1XLHOG845Qa3YTE0/TO3bRg1EQCD+bNc93qumuX6tkYqXmlYA4nYhRDRLC8YeoJ19Zm0E5ZvoQ/+7YLNgtxwvj5OfhFoS0GYNLS9ka9rYLwePklKWa6tfbCtln75daHWFtLms95LGC8WZPFzixJhgkWh6cOvyGkMMxWkGc439qNbgbFklG1OGdzh5ae1KP7ywMtr6d5xfM6eEyBV+Mr/Fy0B3pxFMsnx/2yFUW3OCcpPL8PB0StfPgTRoTQbWwj0blxxXRNuQSasMErGd+up8xKe0kHpBZ4Hr4L6cnika+K2BXdR7ToVOGiQ37vRixNiyO34QVIb/I0AGo5LWLJxDP6Y4E7mhgKkJh4rSU6ihJ1YUZHljibKveO5s0syAEZ9]]></Encrypt>
	<MsgSignature><![CDATA[f41080b7fc392bd3c800d56c1479f307897cb628]]></MsgSignature>
	<TimeStamp>1468298136</TimeStamp>
	<Nonce><![CDATA[1156171062]]></Nonce>
</xml>


研究的时候,借鉴了方倍工作室大神的博客<<微信公众平台开发者中心安全模式消息体加解密实现>>: http://www.cnblogs.com/txw1958/p/weixin-aes-encrypt-decrypt.html

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!