fwq
2022-06-10 ff803def4cd6dea63de5d51f0799fd736bd48e6f
提交 | 用户 | age
5c5945 1 /**
E 2  * 对企业微信发送给企业后台的消息加解密示例代码.
3  * 
4  * @copyright Copyright (c) 1998-2014 Tencent Inc.
5  */
6
7 // ------------------------------------------------------------------------
8
9 package com.qq.weixin.mp.aes;
10
11 import java.io.StringReader;
12
13 import javax.xml.parsers.DocumentBuilder;
14 import javax.xml.parsers.DocumentBuilderFactory;
15
16 import org.w3c.dom.Document;
17 import org.w3c.dom.Element;
18 import org.w3c.dom.NodeList;
19 import org.xml.sax.InputSource;
20
21 /**
22  * XMLParse class
23  *
24  * 提供提取消息格式中的密文及生成回复消息格式的接口.
25  */
26 class XMLParse {
27
28     /**
29      * 提取出xml数据包中的加密消息
30      * @param xmltext 待提取的xml字符串
31      * @return 提取出的加密消息字符串
32      * @throws AesException 
33      */
34     public static Object[] extract(String xmltext) throws AesException     {
35         Object[] result = new Object[3];
36         try {
37             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
38             
39             String FEATURE = null;
40             // This is the PRIMARY defense. If DTDs (doctypes) are disallowed, almost all XML entity attacks are prevented
41             // Xerces 2 only - http://xerces.apache.org/xerces2-j/features.html#disallow-doctype-decl
42             FEATURE = "http://apache.org/xml/features/disallow-doctype-decl";
43             dbf.setFeature(FEATURE, true);
44             
45             // If you can't completely disable DTDs, then at least do the following:
46             // Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-general-entities
47             // Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-general-entities
48             // JDK7+ - http://xml.org/sax/features/external-general-entities 
49             FEATURE = "http://xml.org/sax/features/external-general-entities";
50             dbf.setFeature(FEATURE, false);
51             
52             // Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-parameter-entities
53             // Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-parameter-entities
54             // JDK7+ - http://xml.org/sax/features/external-parameter-entities 
55             FEATURE = "http://xml.org/sax/features/external-parameter-entities";
56             dbf.setFeature(FEATURE, false);
57             
58             // Disable external DTDs as well
59             FEATURE = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
60             dbf.setFeature(FEATURE, false);
61             
62             // and these as well, per Timothy Morgan's 2014 paper: "XML Schema, DTD, and Entity Attacks"
63             dbf.setXIncludeAware(false);
64             dbf.setExpandEntityReferences(false);
65             
66             // And, per Timothy Morgan: "If for some reason support for inline DOCTYPEs are a requirement, then 
67             // ensure the entity settings are disabled (as shown above) and beware that SSRF attacks
68             // (http://cwe.mitre.org/data/definitions/918.html) and denial 
69             // of service attacks (such as billion laughs or decompression bombs via "jar:") are a risk."
70             
71             // remaining parser logic
72             DocumentBuilder db = dbf.newDocumentBuilder();
73             StringReader sr = new StringReader(xmltext);
74             InputSource is = new InputSource(sr);
75             Document document = db.parse(is);
76
77             Element root = document.getDocumentElement();
78             NodeList nodelist1 = root.getElementsByTagName("Encrypt");
79             NodeList nodelist2 = root.getElementsByTagName("ToUserName");
80             result[0] = 0;
81             result[1] = nodelist1.item(0).getTextContent();
82             result[2] = nodelist2.item(0).getTextContent();
83             return result;
84         } catch (Exception e) {
85             e.printStackTrace();
86             throw new AesException(AesException.ParseXmlError);
87         }
88     }
89
90     /**
91      * 生成xml消息
92      * @param encrypt 加密后的消息密文
93      * @param signature 安全签名
94      * @param timestamp 时间戳
95      * @param nonce 随机字符串
96      * @return 生成的xml字符串
97      */
98     public static String generate(String encrypt, String signature, String timestamp, String nonce) {
99
100         String format = "<xml>\n" + "<Encrypt><![CDATA[%1$s]]></Encrypt>\n"
101                 + "<MsgSignature><![CDATA[%2$s]]></MsgSignature>\n"
102                 + "<TimeStamp>%3$s</TimeStamp>\n" + "<Nonce><![CDATA[%4$s]]></Nonce>\n" + "</xml>";
103         return String.format(format, encrypt, signature, timestamp, nonce);
104
105     }
106 }