refactor(wxsdk): 优化微信消息解密流程和接口适配

- 新增 DecryptXmlMsg 方法,支持公众号/服务号 XML 回调加密消息的验签与解密
- 将解密逻辑抽取到 decryptByCipherText 私有方法,减少重复代码
- 修改 WxOfficialController,使用 XmlUtil 解析 XML 并提取 Encrypt 节点的加密信息
- 在控制器中调用 DecryptXmlMsg 进行消息解密,提升解密流程的健壮性
- 添加对 Encrypt 节点缺失或空内容的错误日志和处理
- 优化日志打印格式,增强调试信息的可读性
This commit is contained in:
2026-04-06 22:02:53 +08:00
parent 97b735757d
commit 8a1b729e91
2 changed files with 24 additions and 9 deletions

View File

@@ -139,8 +139,17 @@ public class WxOfficialController extends BaseController {
// 如果有加密参数,进行解密
if (StrUtil.isNotBlank(msg_signature) && StrUtil.isNotBlank(xmlData) && xmlData.contains("Encrypt")) {
try {
Document encryptedDocument = XmlUtil.parseXml(xmlData);
Element encryptedRoot = XmlUtil.getRootElement(encryptedDocument);
Element encryptElement = XmlUtil.getElement(encryptedRoot, "Encrypt");
String encryptedMessage = encryptElement != null ? encryptElement.getTextContent() : "";
if (StrUtil.isBlank(encryptedMessage)) {
log.error("消息解密失败: 未从XML报文中提取到Encrypt节点");
return "error";
}
WXBizJsonMsgCrypt crypt = new WXBizJsonMsgCrypt(getOfficialToken(), getOfficialEncodingAESKey(), getOfficialAppId(tenantId));
xmlData = crypt.DecryptMsg(msg_signature, timestamp, nonce, xmlData);
xmlData = crypt.DecryptXmlMsg(msg_signature, timestamp, nonce, encryptedMessage);
System.out.println("解密后xmlData = " + xmlData);
} catch (Exception e) {
log.error("消息解密失败: {}", e.getMessage());

View File

@@ -248,20 +248,26 @@ public class WXBizJsonMsgCrypt {
// 密钥公众账号的app secret
// 提取密文
Object[] encrypt = JsonParse.extract(postData);
return decryptByCipherText(msgSignature, timeStamp, nonce, encrypt[1].toString());
}
// 验证安全签名
String signature = SHA1.getSHA1(token, timeStamp, nonce, encrypt[1].toString());
/**
* 适配公众号/服务号 XML 回调:直接传入 <Encrypt> 节点中的密文进行验签与解密。
*/
public String DecryptXmlMsg(String msgSignature, String timeStamp, String nonce, String encryptedMsg)
throws AesException {
return decryptByCipherText(msgSignature, timeStamp, nonce, encryptedMsg);
}
private String decryptByCipherText(String msgSignature, String timeStamp, String nonce, String encryptedMsg)
throws AesException {
String signature = SHA1.getSHA1(token, timeStamp, nonce, encryptedMsg);
// 和URL中的签名比较是否相等
// System.out.println("第三方收到URL中的签名" + msg_sign);
// System.out.println("第三方校验签名:" + signature);
if (!signature.equals(msgSignature)) {
throw new AesException(AesException.ValidateSignatureError);
}
// 解密
String result = decrypt(encrypt[1].toString());
return result;
return decrypt(encryptedMsg);
}
/**