首页 > 其他分享 >微信公众号消息加解密

微信公众号消息加解密

时间:2023-04-26 16:23:57浏览次数:51  
标签:encrypt err 微信 加解密 request 公众 wechat error msg

在微信公众号的使用过程中,为了提高信息传输的安全性,可以在服务器配置中将消息加解密模式指定为安全模式

启用安全模式后,公众号主动调用API的情况并不会受影响,只有被动回复用户的消息时才需要对消息进行加解密

官方提供了5种开发语言的示例代码,参照官方给的C++示例代码,本文给出go语言的解密实现:

func handlerEncrypt(body []byte, timestamp, nonce, msg_sig string) (random, rawXMLMsg []byte, err error) {
	request := &WeChatEncryptRequest{}
	err = xml.Unmarshal(body, request)
	if err != nil {
		log.Errorf("unmarshal wechat encrypt request error: %s")
		errors.Wrap(err, "unmarshal wechat encrypt request error")
		return
	}

	// verify msg from wechat signature
	if calcSignature(token, timestamp, nonce, request.Encrypt) != msg_sig {
		log.Errorf("encrypt msg got from wechat verify signature failed")
		errors.New("encrypt msg got from wechat verify signature failed")
		return
	}

	// decode cipher text from base64
	cipherText, err := base64.StdEncoding.DecodeString(request.Encrypt)
	if err != nil {
		log.Errorf("decode wechat encrypt request error: %s", err.Error())
		errors.Wrap(err, "decode wechat encrypt request error")
		return
	}
	// aes decrypt
	plainText, err := aesDecrypt(cipherText, key)
	if err != nil {
		log.Errorf("decrypt wechat encrypt request error: %s", err.Error())
		errors.Wrap(err, "decrypt wechat encrypt request error")
		return
	}

	// get raw wechat encrypt request length
	rawXMLMsgLen := int(ntohl(plainText[16:20]))
	if rawXMLMsgLen < 0 {
		log.Errorf("incorrect msg length: %d", rawXMLMsgLen)
		errors.Wrapf(err, "incorrect msg length: %d", rawXMLMsgLen)
		return
	}

	// verify appid
	appIDOffset := 20 + rawXMLMsgLen
	if len(plainText) <= appIDOffset {
		log.Errorf("msg length too large: %d", rawXMLMsgLen)
		errors.Wrapf(err, "msg length too large: %d", rawXMLMsgLen)
		return
	}
	// verify appid
	if appID != string(plainText[appIDOffset:]) {
		log.Errorf("Received an attack disguised as a WeChat server.")
		errors.New("Received an attack disguised as a WeChat server.")
		return
	}

	// get random which from wechat
	random = plainText[:16:20]

	// raw wechat msg
	rawXMLMsg = plainText[20:appIDOffset:appIDOffset]
	return
}

func calcSignature(args ...string) string {
	sort.Strings(args)
	h := sha1.New()
	for _, arg := range args {
		io.WriteString(h, arg)
	}

	return hex.EncodeToString(h.Sum(nil))
}

func aesDecrypt(cipherText []byte, key []byte) ([]byte, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}
	blockSize := block.BlockSize()
	blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])
	plainText := make([]byte, len(cipherText))
	blockMode.CryptBlocks(plainText, cipherText)
	plainText = pkcs7UnPadding(plainText)
	return plainText, nil
}

func pkcs7UnPadding(data []byte) []byte {
	length := len(data)
	unpadding := int(data[length-1])
	return data[:(length - unpadding)]
}

func ntohl(orderBytes []byte) (n uint32) {
	return uint32(orderBytes[0])<<24 |
		uint32(orderBytes[1])<<16 |
		uint32(orderBytes[2])<<8 |
		uint32(orderBytes[3])
}

完整的代码示例在这里


声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。
Author: mengbin
blog: mengbin
Github: mengbin92
cnblogs: 恋水无意


标签:encrypt,err,微信,加解密,request,公众,wechat,error,msg
From: https://www.cnblogs.com/lianshuiwuyi/p/17356445.html

相关文章

  • 【微信小程序管理】第三方软件的优势有哪些
    ​微信小程序管理软件在提高小程序的安全性、稳定性和可扩展性方面具有重要作用。选择一款优质的微信小程序管理软件,可以帮助企业更好地管理和维护小程序,提高小程序的效率和用户体验,实现企业数字化转型和智能化升级的目标。然而,随着市场上微信小程序管理软件的不断增多,企业在选择......
  • uniapp微信小程序支付
    完全依赖后台接口实现微信小程序只能用微信支付,不用考虑支付宝接口submit(){varself=this;//console.log(this.price,this.payType)varmoney=100000;varamount=this.price;......
  • uniapp微信小程序直播
    https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/liveplayer/live-player-plugin.htmlhttps://docs.qq.com/doc/DZHhzV0FiYXRQV01i不能用<live-player>,因为live-player的src要赋值rtmp格式流视频文件,而<navigator>对应的小程序插件只需要从接......
  • 监控自建MySQL慢查询日志并上报到企业微信集群
    shell脚本如下#!/bin/bash#设置企业微信机器人webhook地址和机器人名称WEBHOOK_URL="你的WEBHOOK_URL"BOT_NAME="MySQLSlowLogBot"#设置慢日志文件路径和记录已发送行数的文件路径LOG_FILE="/data/mysql/mysql-slow-log.log"SENT_LINE_FILE="/tmp/mysql-slow-log.sent......
  • 微信小程序开发
    微信小程序开发者文档:https://developers.weixin.qq.com/miniprogram/dev/component/微信小程序教学视频:https://www.bilibili.com/video/BV1nE41117BQ?p=5&vd_source=77a6f5c488d692a1675c7305a3e29604 1.微信开发者工具介绍: 模拟器底部:可查看页面跳转传递参数添加编译......
  • 微信客户端登陆
    界面:<Windowx:Class="WpfApp1.weixin"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.......
  • 微信小程序 swiper scroll 应用
    swiper演示视图wxml<!--中部上游信息--><swiperclass="swiper"autoplaycircularprevious-margin="20rpx"next-margin="60rpx"><swiper-itemwx:for="{{upstreamList}}"wx:key="id"><......
  • ShareSDK 微信平台注册指南
    注册微信平台账号登录微信开放平台网址微信开放平台网址: https://open.weixin.qq.com/开发者认证1.进入账号中心,进行开发者企业认证2.认证成功后如截图所示注意:开发者企业认证和安卓端需要提交的软著公司需一致,否则需提供软著授权协议证明创建应用填写基本信息按照要求填入填入......
  • 手写签名-微信小程序
    index.wxml<canvastype="2d"id="canvas"bindtouchmove="move"bindtouchstart="start"binderror="error"style="width:{{width}}px;height:{{height}}px;"></canvas><viewclass="b......
  • 微信公众号使用隐藏页判断登录
    <scripttype="text/javascript">   $(document).ready(function(){      document.getElementById("over").style.display="block";      document.getElementById("layout").style.display="block";      //判断......