1
0
mirror of synced 2026-10-07 23:39:43 +08:00

🎨 #4069 【小程序】完善微信小程序消息推送(安全模式)JSON 入参的验签解密能力

This commit is contained in:
Copilot
2026-07-18 16:46:35 +08:00
committed by GitHub
parent 5f9fe24d42
commit 732d4b19f2
2 changed files with 76 additions and 0 deletions

View File

@@ -629,6 +629,23 @@ public class WxMaMessage implements Serializable {
}
}
/**
* 从加密字符串转换.
*
* @param encryptedJson 密文
* @param config 配置存储器对象
* @param timestamp 时间戳
* @param nonce 随机串
* @param msgSignature 签名串
*/
public static WxMaMessage fromEncryptedJson(String encryptedJson, WxMaConfig config,
String timestamp, String nonce, String msgSignature) {
WxMaMessage encryptedMessage = fromJson(encryptedJson);
String plainText = new WxMaCryptUtils(config).decryptContent(msgSignature, timestamp, nonce,
encryptedMessage.getEncrypt());
return fromJson(plainText);
}
public static WxMaMessage fromEncryptedJson(InputStream inputStream, WxMaConfig config) {
try {
return fromEncryptedJson(IOUtils.toString(inputStream, StandardCharsets.UTF_8), config);
@@ -637,6 +654,16 @@ public class WxMaMessage implements Serializable {
}
}
public static WxMaMessage fromEncryptedJson(InputStream inputStream, WxMaConfig config,
String timestamp, String nonce, String msgSignature) {
try {
return fromEncryptedJson(IOUtils.toString(inputStream, StandardCharsets.UTF_8), config,
timestamp, nonce, msgSignature);
} catch (IOException e) {
throw new WxRuntimeException(e);
}
}
@Override
public String toString() {
return this.toJson();

View File

@@ -2,14 +2,21 @@ package cn.binarywang.wx.miniapp.bean;
import cn.binarywang.wx.miniapp.bean.xpay.WxMaXPayTeamInfo;
import cn.binarywang.wx.miniapp.constant.WxMaConstants;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import cn.binarywang.wx.miniapp.util.crypt.WxMaCryptUtils;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.error.WxRuntimeException;
import me.chanjar.weixin.common.util.crypto.SHA1;
import org.testng.annotations.Test;
import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import static org.assertj.core.api.Assertions.as;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
@@ -459,6 +466,48 @@ public class WxMaMessageTest {
assertEquals(msg.getRequestId(), "req_005");
}
@Test
public void testFromEncryptedJsonWithSignature() {
WxMaDefaultConfigImpl config = buildMessagePushConfig();
String plainJson = "{\"ToUserName\":\"gh_123456789abc\",\"FromUserName\":\"fromUser\",\"CreateTime\":1710000000,"
+ "\"MsgType\":\"event\",\"Event\":\"subscribe_msg_popup_event\"}";
String encrypt = new WxMaCryptUtils(config).encrypt("1234567890abcdef", plainJson);
String timestamp = "1710000000";
String nonce = "nonce123";
String msgSignature = SHA1.gen(config.getToken(), timestamp, nonce, encrypt);
String encryptedJson = "{\"Encrypt\":\"" + encrypt + "\"}";
WxMaMessage wxMessage = WxMaMessage.fromEncryptedJson(new ByteArrayInputStream(
encryptedJson.getBytes(StandardCharsets.UTF_8)), config, timestamp, nonce, msgSignature);
assertEquals(wxMessage.getToUser(), "gh_123456789abc");
assertEquals(wxMessage.getFromUser(), "fromUser");
assertEquals(wxMessage.getCreateTime(), new Integer(1710000000));
assertEquals(wxMessage.getMsgType(), WxConsts.XmlMsgType.EVENT);
assertEquals(wxMessage.getEvent(), "subscribe_msg_popup_event");
}
@Test
public void testFromEncryptedJsonWithSignatureInvalidMsgSignature() {
WxMaDefaultConfigImpl config = buildMessagePushConfig();
String plainJson = "{\"ToUserName\":\"gh_123456789abc\",\"FromUserName\":\"fromUser\"}";
String encrypt = new WxMaCryptUtils(config).encrypt("1234567890abcdef", plainJson);
String encryptedJson = "{\"Encrypt\":\"" + encrypt + "\"}";
assertThatThrownBy(() -> WxMaMessage.fromEncryptedJson(encryptedJson, config,
"1710000000", "nonce123", "invalidSignature"))
.isInstanceOf(WxRuntimeException.class)
.hasMessageContaining("加密消息签名校验失败");
}
private WxMaDefaultConfigImpl buildMessagePushConfig() {
WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
config.setAppid("wx1234567890abcdef");
config.setToken("testToken");
config.setAesKey("abcdefghijklmnopqrstuvwxyz0123456789ABCDEFG");
return config;
}
/**
* 虚拟支付 iOS 退款查询通知事件 xpay_subscribe_ios_refund_query_notify 测试用例(XML格式)
*/