diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMessage.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMessage.java index 83073850d..6d01e5803 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMessage.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMessage.java @@ -629,6 +629,23 @@ public static WxMaMessage fromEncryptedJson(String encryptedJson, WxMaConfig con } } + /** + * 从加密字符串转换. + * + * @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 static WxMaMessage fromEncryptedJson(InputStream inputStream, WxMaConfig } } + 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(); diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/WxMaMessageTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/WxMaMessageTest.java index a25589d64..0b7060e79 100644 --- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/WxMaMessageTest.java +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/WxMaMessageTest.java @@ -2,14 +2,21 @@ 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 @@ private void checkXPayComplaintNotifyMessage(WxMaMessage msg) { 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格式) */