提交 | 用户 | 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 |
} |