`

微信公众平台的TOKEN安全验证

    博客分类:
  • Java
阅读更多

本文目标:学习一种比较安全的服务器间互相验证身份的方式。 

 

问题:开发微信公众平台接口,开发者的服务器为了确保请求是否来自微信服务器,应该如何去做?

 

1)  在微信管理页面上填写URL和TOKEN,开发者服务器上也记录同样的TOKEN。

 

2)  微信服务器发送HTTP请求,附带上参数(注意TOKEN是不会被传输的)

 

参数 描述
signature 微信加密签名
timestamp 时间戳
nonce 随机数
echostr 随机字符串

 其中signature值通过如下摘要运算得出:

1. 将token、timestamp、nonce三个参数进行字典序排序
2. 将三个参数字符串拼接成一个字符串进行sha1加密(这个加密是不可逆的),并将结果的byte[]转换为16进制字符串

 

3)  开发者服务器接收到signature,timestamp,nonce,echostr参数,跟服务器做同样的摘要运算,得到预期的一个signatrue,然后对比微信服务器发送过来的signature参数,如果相同,证明双方的TOKEN是一致的,开发者服务器确实接收到了来自微信服务器的请求,开发者服务器最后返回echostr,以告诉微信服务器接入成功。具体的开发者服务器校验逻辑代码如下显示。

 

 

package message;

import java.security.*;
import java.util.Arrays;

/***
 * 微信消息接口认证token摘要类
 * 
 * 这个摘要类实现为单例,校验一个签名是否合法的例子如下
 * <pre>
 * WeixinMessageDigest wxDigest = WeixinMessageDigest.getInstance();
 * boolean bValid = wxDigest.validate(signature, timestamp, nonce);
 * </pre>
 * 
 * 
 * @author liguocai
 */
public final class WeixinMessageDigest {
	
	/**
	 * 单例持有类
	 * @author liguocai
	 *
	 */
	private static class SingletonHolder{
		static final WeixinMessageDigest INSTANCE = new WeixinMessageDigest();
	}
	
	/**
	 * 获取单例
	 * @return
	 */
	public static WeixinMessageDigest getInstance() {
		return SingletonHolder.INSTANCE;
	}
	
	private MessageDigest digest;
	
	private WeixinMessageDigest() {
		try {
			digest = MessageDigest.getInstance("SHA-1");
		} catch(Exception e) {
			throw new InternalError("init MessageDigest error:" + e.getMessage());
		}
	}

	

	/**
	 * 将字节数组转换成16进制字符串
	 * @param b
	 * @return
	 */
	private static String byte2hex(byte[] b) {
		StringBuilder sbDes = new StringBuilder();
		String tmp = null;
		for (int i = 0; i < b.length; i++) {
			tmp = (Integer.toHexString(b[i] & 0xFF));
			if (tmp.length() == 1) {
				sbDes.append("0");
			}
			sbDes.append(tmp);
		}
		return sbDes.toString();
	}
	
	private String encrypt(String strSrc) {
		String strDes = null;
		byte[] bt = strSrc.getBytes();
		digest.update(bt);
		strDes = byte2hex(digest.digest());
		return strDes;
	}

	/**
	 * 校验请求的签名是否合法
	 * 
	 * 加密/校验流程:
     * 1. 将token、timestamp、nonce三个参数进行字典序排序
     * 2. 将三个参数字符串拼接成一个字符串进行sha1加密
	 * 3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
	 * @param signature
	 * @param timestamp
	 * @param nonce
	 * @return
	 */
	public boolean validate(String signature, String timestamp, String nonce){
		//1. 将token、timestamp、nonce三个参数进行字典序排序
		String token = getToken();
		String[] arrTmp = { token, timestamp, nonce };
		Arrays.sort(arrTmp);
		StringBuffer sb = new StringBuffer();
		//2.将三个参数字符串拼接成一个字符串进行sha1加密
		for (int i = 0; i < arrTmp.length; i++) {
			sb.append(arrTmp[i]);
		}
		String expectedSignature = encrypt(sb.toString());
		//3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
		if(expectedSignature.equals(signature)){
			return true;
		}
		return false;
	}
	
	private String getToken(){
		return "111111";
	}

	public static void main(String[] args) {
		
		String signature="f86944503c10e7caefe35d6bc19a67e6e8d0e564";//加密需要验证的签名
		String timestamp="1371608072";//时间戳
		String nonce="1372170854";//随机数
		
		WeixinMessageDigest wxDigest = WeixinMessageDigest.getInstance();
		boolean bValid = wxDigest.validate(signature, timestamp, nonce);		
		if (bValid) {
			System.out.println("token 验证成功!");
		}else {
			System.out.println("token 验证失败!");
		}
	}

}

 

4) 这个摘要对比的技术,同样适用于单点登录、服务期间互相调用的身份验证,前提是每台服务器都持有相同的TOKEN。此外,有些细节可以优化,例如通过timestamp对签名做超时的处理,超时的签名默认不通过;请求的参数可以加上IP, USERID等额外信息;返回的echostr可以再次与TOKEN做摘要,可以使微信服务器确保接受来自开发者服务器的响应,但是微信服务器没有这么做,也许它本身已经做了足够安全控制。

 

微信消息接口文档:

http://mp.weixin.qq.com/wiki/index.php?title=%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3%E6%8C%87%E5%8D%97

4
5
分享到:
评论

相关推荐

    微信公众平台Token验证

    微信公众平台Token验证源码,java版!

    PHP实现微信公众号验证Token的示例代码

    主要介绍了PHP实现微信公众号验证Token的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    微信公众平台TOKEN验证

    描述:微信公众平台TOKEN验证PHP网页文件。在服务器端的PHP网页,测试通过。 资源名称:微信公众平台TOKEN验证

    JAVA微信公众平台Token验证

    首先要开启开发模式必须要进行Token的一个验证,你给出一个地址,微信发送请求,然后你给出相应,就这么简单。虽然说是简单,但是这是事后才说的,官方只有PHP的DEMO,我用JAVA开发的时候各种蛋疼不会弄,不过好在...

    .net微信公众平台验证Token并在关注时发送欢迎语

    .net微信公众平台验证Token并在关注时发送欢迎语,vs2010源码;.net微信公众平台验证Token并在关注时发送欢迎语;.net微信公众平台验证Token并在关注时发送欢迎语;.net微信公众平台验证Token并在关注时发送欢迎语;...

    [点微]微信平台微信接口提交提示:TOKEN验证失败、URL请求超时1

    [点微]微信平台Discuz 论坛微信运营首选平台微信接口提交提示:TOKEN验证失败、URL请求超时我们在提交开发者中心设置的URL和TOKEN的时候,往往会

    rar文件 微信公众平台ToKen验证

    可以直接复制代码进行验证,带有自动回复功能,经测试,效果很好,android和ios全面兼容

    微信公众开发token验证文件

    微信公众号开发token验证文件,包括自动回复消息相关信息

    微信小程序url与token设置详解

    // 后台填写的token,在微信公众平台启用 $wechatObj = new wechatAPI(); $wechatObj-&gt;isValid(); class wechatAPI { public function isValid()//验证微信接口,验证函数以外的代码和微信公众号开发token设置相同 ...

    微信公众平台企业号接口token验证、回调 PHP版(完整案例)

    微信公众平台企业号验证接口、回调 PHP版,本人为了解决这个企业号的验证和发送消息的问题,整整研究了几天时间,因为微信企业号刚推出来,网上资料太少了!后来在一些朋友的帮助下和本人反复调试完善下,终于整理...

    微信公众平台开发的验证服务器和自动回复用户消息

    该例子仅简单的对微信服务器验证和用户信息的自动回复做了处理,为初学者在怎样开始微信公众平台的开发毫无头绪的时候提供一点儿帮助. 本例子使用了.net4.0框架,直接用VS2010打开网站,找到该文件夹,打开即可. 将...

    微信公众平台链接代码

    微信公众平台token验证,微信服务器和自己网站的连接。响应客户端的点击按钮事件,只包括详细相应事件方法

    微信公众平台接口使用-连接验证(asp.net)

    已经通过验证。 onst string TOKEN = "your token name"; //TOKEN签名 protected void Page_Load(object sender, EventArgs e) { string postStr = ""; if (Request.HttpMethod.ToLower() == "post")//判断传输...

    微信公众平台接入Java实例

    利用java实现微信公众平台接入,实现TOKEN验证,以及信息的回复接口实现。

    微信公众平台JavaSDKweixin-popular.zip

    weixin-popular 包括微信公众平台基础API与支付API,提供便捷的API调用接口. API 列表: TokenAPI access_token 获取 MediaAPI 多媒体上传下载(临时素材) ...

    php的微信公众平台开发接口类.zip

    &lt;?... define("TOKEN", "weixin"); $wechatObj = new wechatCallbackapiTest(); ...isset($_GET['echostr'])) { ... //验证消息 ... }这是一个php的微信公众平台开发接口类,需要的朋友可以下载使用

    微信公众平台企业号token验证接口、回调 PHP版(完整案例)

    微信公众平台企业号验证接口、回调 PHP版,本人为了解决这个企业号的验证和发送消息的问题,整整研究了几天时间,因为微信企业号刚推出来,网上资料太少了!后来在一些朋友的帮助下和本人反复调试完善下,终于整理...

    微信公众号服务器验证Token步骤图解

    服务器验证Token验证分为以下及步骤 一,在微信公众号平台上设置 1.1打开微信公众号平台 1.2打开”开发“中的&lt;基本配置&gt; 1.3点击基本配置页面里的修改配置 1.4输入URL: url填写:http://外网IP:端口号/wx 。...

    php版微信公众平台开发之验证步骤实例详解

    微信公众平台开发我们现在做得比较多了,这里给各位介绍的是一个入门级别的微信公众平台验证基础知识了,有兴趣的和小编来看看。 开发微信的时候 需要验证一下,在官方开发者中心哪里有可以下源代码,登录到 公众帐号后 ...

    微信小程序url,token设置

    // 后台填写的token,在微信公众平台启用 $wechatObj = new wechatAPI(); $wechatObj-&gt;isValid(); class wechatAPI { public function isValid()//验证微信接口,验证函数以外的代码和微信公众号开发token设置相同 {...

Global site tag (gtag.js) - Google Analytics