微信测试账号 (2)-消息验证sha1签名

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wangb_java/article/details/53868438

第1篇中实现了收发微信消息,但是没有做验证,本篇将介绍微信如何使用sha签名,对消息进行认证。其中安全相关的概念,如sha1散列值、签名等,可参考web安全(1)

验证参数

	@GetMapping("/handler")
	public String handler(@RequestParam Map<String,String> map)  {

回顾 第1篇的get验证方法,在map中会收到微信发过来的4个参数,如下:

signature:签名,是微信用timestamp、nonce、你的token三个参数进行sha1算法得出的,用于验证消息来源。

echostr:随机字符串,第1篇演示过,如果signature签名验证成功,返回echostr给微信即可确认。

timestamp:时间戳(秒),可用于阻止重放攻击,下面会讲。

nonce:随机数,增加签名的不可预测性。

验证方法 

1)将token、timestamp、nonce三个参数进行字典序排序

2)将三个参数字符串拼接成一个字符串进行sha1加密

3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信

token的作用

以上3条是微信官网原文,注意:我在web安全(1)中讲过,sha散列值与signature签名是两个不同的东西。消息参数中nonce和timestamp谁都可以生成,如果只对这样的内容进行sha1加密,实际作用只能是消息摘要,无法真正起到签名的作用,黑客可以自己生成nonce和timestamp及其sha1摘要,冒名微信请求我们的服务器。

而token是我们在微信网站中配置的,加入token以后的sha1摘要就真正起到了签名的作用,因为黑客不知道token,要伪造包含你token的假sha1摘要是相当困难的。除非你把token设的很短或很简单。

重放攻击

即使黑客无法自己生成签名,他只要知道了一次正常请求的get参数及签名,就可以反复使用这次传参伪装为真实用户,但他不能擅改时间时间戳,这会导致签名不一致。所以我们可以检查时间戳与当前时间的差值,超过一定时间,就判定是非法请求。

实现代码

添加commons-codec依赖,是apache开源的用于一些加解密之类的算法,下面会用它来实现sha1签名。

<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
</dependency>

	@GetMapping("/handler")
	public String handler(@RequestParam Map<String,String> map)  {
		//1.将三个参数存入数组
		String[] array = {token,map.get("timestamp"),map.get("nonce")};
		//调用数组的排序方法,进行排序
		Arrays.sort(array);
		//2.调用spring的转换方法,将数组中已排序过的三个参数拼接成一个字符串
		String s = StringUtils.arrayToDelimitedString(array, "");
		//调用commons-codec的sha1加密方法生成签名
		String signature = DigestUtils.sha1Hex(s);
		//3.与signature对比,确认消息是否源自微信
		if(!map.get("signature").equals(signature)){
                        //验证不成功,随便回一个无关的内容
			return "fail";
		}
                //验证成功
		return map.get("echostr");

回复消息和success

以上get验证通过后,每次用post请求业务消息都要先进行以上验证,保证消息真实源自微信,再去做业务处理。但是以后不再有echostr这个参数,而且可以根据业务场景回复特定内容,如第1篇回复hello world。

如果业务处理后不需要任何回复,可回复“success”,通知微信处理成功,否则微信会提示用户错误信息。

消息加密

以上消息都是明文发送的,并没有加密,这是微信默认的设置。假如要对消息进行加密,需要登录账号进行配置,而测试账号并没有相关配置,以后讲正式账号时再详细介绍。

猜你喜欢

转载自blog.csdn.net/wangb_java/article/details/53868438