refactor(wxsdk): 优化微信消息解密流程和接口适配
- 新增 DecryptXmlMsg 方法,支持公众号/服务号 XML 回调加密消息的验签与解密 - 将解密逻辑抽取到 decryptByCipherText 私有方法,减少重复代码 - 修改 WxOfficialController,使用 XmlUtil 解析 XML 并提取 Encrypt 节点的加密信息 - 在控制器中调用 DecryptXmlMsg 进行消息解密,提升解密流程的健壮性 - 添加对 Encrypt 节点缺失或空内容的错误日志和处理 - 优化日志打印格式,增强调试信息的可读性
This commit is contained in:
@@ -139,8 +139,17 @@ public class WxOfficialController extends BaseController {
|
|||||||
// 如果有加密参数,进行解密
|
// 如果有加密参数,进行解密
|
||||||
if (StrUtil.isNotBlank(msg_signature) && StrUtil.isNotBlank(xmlData) && xmlData.contains("Encrypt")) {
|
if (StrUtil.isNotBlank(msg_signature) && StrUtil.isNotBlank(xmlData) && xmlData.contains("Encrypt")) {
|
||||||
try {
|
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));
|
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);
|
System.out.println("解密后xmlData = " + xmlData);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("消息解密失败: {}", e.getMessage());
|
log.error("消息解密失败: {}", e.getMessage());
|
||||||
|
|||||||
@@ -248,20 +248,26 @@ public class WXBizJsonMsgCrypt {
|
|||||||
// 密钥,公众账号的app secret
|
// 密钥,公众账号的app secret
|
||||||
// 提取密文
|
// 提取密文
|
||||||
Object[] encrypt = JsonParse.extract(postData);
|
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)) {
|
if (!signature.equals(msgSignature)) {
|
||||||
throw new AesException(AesException.ValidateSignatureError);
|
throw new AesException(AesException.ValidateSignatureError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解密
|
return decrypt(encryptedMsg);
|
||||||
String result = decrypt(encrypt[1].toString());
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user