Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Q
qk_backend
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
quanku
qk_backend
Commits
ca818d19
Commit
ca818d19
authored
Oct 13, 2023
by
shiyu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
公众号
parent
dd90a984
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
788 additions
and
22 deletions
+788
-22
ch-core/src/main/resources/application-dev.yml
ch-core/src/main/resources/application-dev.yml
+5
-0
ch-core/src/main/resources/application-prod.yml
ch-core/src/main/resources/application-prod.yml
+5
-0
ch-wx-api/src/main/java/com/wwdz/ch/wx/api/OfficialAccountApi.java
.../src/main/java/com/wwdz/ch/wx/api/OfficialAccountApi.java
+5
-2
ch-wx-api/src/main/java/com/wwdz/ch/wx/api/OfficialAccountController.java
...in/java/com/wwdz/ch/wx/api/OfficialAccountController.java
+41
-20
ch-wx-api/src/main/java/com/wwdz/ch/wx/api/aes/AesException.java
...pi/src/main/java/com/wwdz/ch/wx/api/aes/AesException.java
+59
-0
ch-wx-api/src/main/java/com/wwdz/ch/wx/api/aes/ByteGroup.java
...x-api/src/main/java/com/wwdz/ch/wx/api/aes/ByteGroup.java
+26
-0
ch-wx-api/src/main/java/com/wwdz/ch/wx/api/aes/PKCS7Encoder.java
...pi/src/main/java/com/wwdz/ch/wx/api/aes/PKCS7Encoder.java
+67
-0
ch-wx-api/src/main/java/com/wwdz/ch/wx/api/aes/SHA1.java
ch-wx-api/src/main/java/com/wwdz/ch/wx/api/aes/SHA1.java
+61
-0
ch-wx-api/src/main/java/com/wwdz/ch/wx/api/aes/WXBizMsgCrypt.java
...i/src/main/java/com/wwdz/ch/wx/api/aes/WXBizMsgCrypt.java
+300
-0
ch-wx-api/src/main/java/com/wwdz/ch/wx/api/aes/WXBizMsgCryptTest.java
...c/main/java/com/wwdz/ch/wx/api/aes/WXBizMsgCryptTest.java
+148
-0
ch-wx-api/src/main/java/com/wwdz/ch/wx/api/aes/XMLParse.java
ch-wx-api/src/main/java/com/wwdz/ch/wx/api/aes/XMLParse.java
+71
-0
No files found.
ch-core/src/main/resources/application-dev.yml
View file @
ca818d19
...
...
@@ -10,6 +10,11 @@ dts:
# 商户证书文件路径
# 请参考“商户证书”一节 https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=4_3
key-path
:
xxxxx
#微信公众号服务器配置信息
officialaccount—appid
:
wx7db8eb146a194083
officialaccount-secret
:
daecb3de53841fe1a787bc9849ac3406
officialaccount-token
:
Uu6GHYOiP1xJ6GaBMyXfnITufAGJTe3Q
officialaccount-key
:
noeN1amYRvzrVmE2GnC5VnsIfgPEmv6bhX54wJOARlM
#通知相关配置
notify
:
...
...
ch-core/src/main/resources/application-prod.yml
View file @
ca818d19
...
...
@@ -9,6 +9,11 @@ dts:
# 商户证书文件路径
# 请参考“商户证书”一节 https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=4_3
key-path
:
xxxxx
#微信公众号服务器配置信息
officialaccount—appid
:
wx7db8eb146a194083
officialaccount-secret
:
daecb3de53841fe1a787bc9849ac3406
officialaccount-token
:
Uu6GHYOiP1xJ6GaBMyXfnITufAGJTe3Q
officialaccount-key
:
noeN1amYRvzrVmE2GnC5VnsIfgPEmv6bhX54wJOARlM
#通知相关配置
notify
:
...
...
ch-wx-api/src/main/java/com/wwdz/ch/wx/api/OfficialAccountApi.java
View file @
ca818d19
...
...
@@ -7,6 +7,7 @@ import com.xxdxxs.utils.StringUtils;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Component
;
import
java.util.concurrent.TimeUnit
;
...
...
@@ -19,9 +20,11 @@ public class OfficialAccountApi {
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
OfficialAccountApi
.
class
);
private
final
static
String
APPID
=
"wx7db8eb146a194083"
;
@Value
(
"${dts.wx.officialaccount-appid}"
)
private
String
APPID
;
private
final
static
String
APPSECRET
=
"daecb3de53841fe1a787bc9849ac3406"
;
@Value
(
"${dts.wx.officialaccount-secret}"
)
private
String
APPSECRET
;
private
final
static
String
GET_ACCESSTOKEN_URL
=
"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential"
;
...
...
ch-wx-api/src/main/java/com/wwdz/ch/wx/api/OfficialAccountController.java
View file @
ca818d19
...
...
@@ -2,6 +2,7 @@ package com.wwdz.ch.wx.api;
import
com.alibaba.fastjson.JSONObject
;
import
com.wwdz.ch.wx.api.aes.WXBizMsgCrypt
;
import
com.wwdz.ch.wx.util.StringUtil
;
import
com.xxdxxs.utils.JsonUtils
;
import
com.xxdxxs.utils.StringUtils
;
...
...
@@ -9,6 +10,8 @@ import com.xxdxxs.utils.XmlUtils;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.util.CollectionUtils
;
import
org.springframework.web.bind.annotation.*
;
import
javax.servlet.http.HttpServletRequest
;
...
...
@@ -28,6 +31,20 @@ public class OfficialAccountController {
private
final
static
String
UNSUBSCRIBE_EVENT
=
"unsubscribe"
;
@Value
(
"${dts.wx.officialaccount-token}"
)
private
String
OFFICIALACCOUNTTOKEN
;
@Value
(
"${dts.wx.officialaccount-key}"
)
private
String
OFFICIALACCOUNTKEY
;
@Value
(
"${dts.wx.officialaccount-appid}"
)
private
String
APPID
;
@Value
(
"${dts.wx.officialaccount-secret}"
)
private
String
APPSECRET
;
@Autowired
OfficialAccountApi
officialAccountApi
;
...
...
@@ -87,28 +104,35 @@ public class OfficialAccountController {
@RequestParam
(
required
=
false
,
name
=
"echostr"
)
String
echostr
,
@RequestBody
(
required
=
false
)
String
xmlInfo
,
HttpServletResponse
response
)
throws
IOException
{
logger
.
info
(
"222222222222222 :{}"
,
echostr
);
System
.
out
.
println
(
"接入失败"
);
return
echostr
+
""
;
}
@RequestMapping
(
value
=
"/getSubscribeNotice2"
)
public
Object
getSubscribeNotice2
(
@RequestParam
(
required
=
false
,
name
=
"signature"
)
String
signature
,
@RequestParam
(
required
=
false
,
name
=
"timestamp"
)
String
timestamp
,
@RequestParam
(
required
=
false
,
name
=
"nonce"
)
String
nonce
,
@RequestParam
(
required
=
false
,
name
=
"echostr"
)
String
echostr
,
@RequestBody
(
required
=
false
)
String
xmlInfo
,
HttpServletResponse
response
)
throws
IOException
{
logger
.
info
(
"33333 :{}"
,
echostr
);
System
.
out
.
println
(
"接入失败"
);
return
Long
.
valueOf
(
echostr
);
try
{
logger
.
info
(
"接收公众号推送信息校验 -> appid: {}, signature:{}, timestamp:{}, nonce:{}, echostr : {}"
,
APPID
,
signature
,
timestamp
,
nonce
,
echostr
);
WXBizMsgCrypt
wxBizMsgCrypt
=
new
WXBizMsgCrypt
(
OFFICIALACCOUNTTOKEN
,
OFFICIALACCOUNTKEY
,
APPID
);
if
(
StringUtils
.
hasLength
(
echostr
))
{
return
Long
.
valueOf
(
echostr
.
trim
());
}
logger
.
info
(
"公众号推送的消息原文 -> {}"
,
xmlInfo
);
String
xmlStr
=
wxBizMsgCrypt
.
decryptMsg
(
signature
,
timestamp
,
nonce
,
xmlInfo
);
logger
.
info
(
"解密后获取公众号推送的信息内容 : {}"
,
xmlStr
);
List
<
Map
<
String
,
String
>>
list
=
XmlUtils
.
fromXml
(
xmlStr
,
"xml"
);
if
(!
CollectionUtils
.
isEmpty
(
list
))
{
Map
<
String
,
String
>
contentMap
=
list
.
get
(
0
);
String
event
=
contentMap
.
get
(
"Event"
);
if
(
SUBSCRIBE_EVENT
.
equals
(
event
)
||
UNSUBSCRIBE_EVENT
.
equals
(
event
))
{
String
userOpenId
=
contentMap
.
get
(
"FromUserName"
);
String
createTime
=
contentMap
.
get
(
"CreateTime"
);
Date
date
=
new
Date
(
createTime
);
logger
.
info
(
"openId:{}, event :{}, time:{}"
,
userOpenId
,
event
,
date
);
}
}
}
catch
(
Exception
e
)
{
logger
.
error
(
"公众号推送信息error : {}"
,
e
);
}
return
"success"
;
}
@RequestMapping
(
value
=
"/getToken"
)
public
String
getToken
(){
String
token
=
null
;
...
...
@@ -120,7 +144,4 @@ public class OfficialAccountController {
return
token
;
}
public
static
void
main
(
String
[]
args
)
{
System
.
out
.
println
(
StringUtil
.
generateRandomString
(
32
));
}
}
ch-wx-api/src/main/java/com/wwdz/ch/wx/api/aes/AesException.java
0 → 100644
View file @
ca818d19
package
com.wwdz.ch.wx.api.aes
;
@SuppressWarnings
(
"serial"
)
public
class
AesException
extends
Exception
{
public
final
static
int
OK
=
0
;
public
final
static
int
ValidateSignatureError
=
-
40001
;
public
final
static
int
ParseXmlError
=
-
40002
;
public
final
static
int
ComputeSignatureError
=
-
40003
;
public
final
static
int
IllegalAesKey
=
-
40004
;
public
final
static
int
ValidateAppidError
=
-
40005
;
public
final
static
int
EncryptAESError
=
-
40006
;
public
final
static
int
DecryptAESError
=
-
40007
;
public
final
static
int
IllegalBuffer
=
-
40008
;
//public final static int EncodeBase64Error = -40009;
//public final static int DecodeBase64Error = -40010;
//public final static int GenReturnXmlError = -40011;
private
int
code
;
private
static
String
getMessage
(
int
code
)
{
switch
(
code
)
{
case
ValidateSignatureError:
return
"签名验证错误"
;
case
ParseXmlError:
return
"xml解析失败"
;
case
ComputeSignatureError:
return
"sha加密生成签名失败"
;
case
IllegalAesKey:
return
"SymmetricKey非法"
;
case
ValidateAppidError:
return
"appid校验失败"
;
case
EncryptAESError:
return
"aes加密失败"
;
case
DecryptAESError:
return
"aes解密失败"
;
case
IllegalBuffer:
return
"解密后得到的buffer非法"
;
// case EncodeBase64Error:
// return "base64加密错误";
// case DecodeBase64Error:
// return "base64解密错误";
// case GenReturnXmlError:
// return "xml生成失败";
default
:
return
null
;
// cannot be
}
}
public
int
getCode
()
{
return
code
;
}
AesException
(
int
code
)
{
super
(
getMessage
(
code
));
this
.
code
=
code
;
}
}
ch-wx-api/src/main/java/com/wwdz/ch/wx/api/aes/ByteGroup.java
0 → 100644
View file @
ca818d19
package
com.wwdz.ch.wx.api.aes
;
import
java.util.ArrayList
;
class
ByteGroup
{
ArrayList
<
Byte
>
byteContainer
=
new
ArrayList
<
Byte
>();
public
byte
[]
toBytes
()
{
byte
[]
bytes
=
new
byte
[
byteContainer
.
size
()];
for
(
int
i
=
0
;
i
<
byteContainer
.
size
();
i
++)
{
bytes
[
i
]
=
byteContainer
.
get
(
i
);
}
return
bytes
;
}
public
ByteGroup
addBytes
(
byte
[]
bytes
)
{
for
(
byte
b
:
bytes
)
{
byteContainer
.
add
(
b
);
}
return
this
;
}
public
int
size
()
{
return
byteContainer
.
size
();
}
}
ch-wx-api/src/main/java/com/wwdz/ch/wx/api/aes/PKCS7Encoder.java
0 → 100644
View file @
ca818d19
/**
* 对公众平台发送给公众账号的消息加解密示例代码.
*
* @copyright Copyright (c) 1998-2014 Tencent Inc.
*/
// ------------------------------------------------------------------------
package
com.wwdz.ch.wx.api.aes
;
import
java.nio.charset.Charset
;
import
java.util.Arrays
;
/**
* 提供基于PKCS7算法的加解密接口.
*/
class
PKCS7Encoder
{
static
Charset
CHARSET
=
Charset
.
forName
(
"utf-8"
);
static
int
BLOCK_SIZE
=
32
;
/**
* 获得对明文进行补位填充的字节.
*
* @param count 需要进行填充补位操作的明文字节个数
* @return 补齐用的字节数组
*/
static
byte
[]
encode
(
int
count
)
{
// 计算需要填充的位数
int
amountToPad
=
BLOCK_SIZE
-
(
count
%
BLOCK_SIZE
);
if
(
amountToPad
==
0
)
{
amountToPad
=
BLOCK_SIZE
;
}
// 获得补位所用的字符
char
padChr
=
chr
(
amountToPad
);
String
tmp
=
new
String
();
for
(
int
index
=
0
;
index
<
amountToPad
;
index
++)
{
tmp
+=
padChr
;
}
return
tmp
.
getBytes
(
CHARSET
);
}
/**
* 删除解密后明文的补位字符
*
* @param decrypted 解密后的明文
* @return 删除补位字符后的明文
*/
static
byte
[]
decode
(
byte
[]
decrypted
)
{
int
pad
=
(
int
)
decrypted
[
decrypted
.
length
-
1
];
if
(
pad
<
1
||
pad
>
32
)
{
pad
=
0
;
}
return
Arrays
.
copyOfRange
(
decrypted
,
0
,
decrypted
.
length
-
pad
);
}
/**
* 将数字转化成ASCII码对应的字符,用于对明文进行补码
*
* @param a 需要转化的数字
* @return 转化得到的字符
*/
static
char
chr
(
int
a
)
{
byte
target
=
(
byte
)
(
a
&
0xFF
);
return
(
char
)
target
;
}
}
ch-wx-api/src/main/java/com/wwdz/ch/wx/api/aes/SHA1.java
0 → 100644
View file @
ca818d19
/**
* 对公众平台发送给公众账号的消息加解密示例代码.
*
* @copyright Copyright (c) 1998-2014 Tencent Inc.
*/
// ------------------------------------------------------------------------
package
com.wwdz.ch.wx.api.aes
;
import
java.security.MessageDigest
;
import
java.util.Arrays
;
/**
* SHA1 class
*
* 计算公众平台的消息签名接口.
*/
class
SHA1
{
/**
* 用SHA1算法生成安全签名
* @param token 票据
* @param timestamp 时间戳
* @param nonce 随机字符串
* @param encrypt 密文
* @return 安全签名
* @throws AesException
*/
public
static
String
getSHA1
(
String
token
,
String
timestamp
,
String
nonce
,
String
encrypt
)
throws
AesException
{
try
{
String
[]
array
=
new
String
[]
{
token
,
timestamp
,
nonce
,
encrypt
};
StringBuffer
sb
=
new
StringBuffer
();
// 字符串排序
Arrays
.
sort
(
array
);
for
(
int
i
=
0
;
i
<
4
;
i
++)
{
sb
.
append
(
array
[
i
]);
}
String
str
=
sb
.
toString
();
// SHA1签名生成
MessageDigest
md
=
MessageDigest
.
getInstance
(
"SHA-1"
);
md
.
update
(
str
.
getBytes
());
byte
[]
digest
=
md
.
digest
();
StringBuffer
hexstr
=
new
StringBuffer
();
String
shaHex
=
""
;
for
(
int
i
=
0
;
i
<
digest
.
length
;
i
++)
{
shaHex
=
Integer
.
toHexString
(
digest
[
i
]
&
0xFF
);
if
(
shaHex
.
length
()
<
2
)
{
hexstr
.
append
(
0
);
}
hexstr
.
append
(
shaHex
);
}
return
hexstr
.
toString
();
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
throw
new
AesException
(
AesException
.
ComputeSignatureError
);
}
}
}
ch-wx-api/src/main/java/com/wwdz/ch/wx/api/aes/WXBizMsgCrypt.java
0 → 100644
View file @
ca818d19
This diff is collapsed.
Click to expand it.
ch-wx-api/src/main/java/com/wwdz/ch/wx/api/aes/WXBizMsgCryptTest.java
0 → 100644
View file @
ca818d19
package
com.wwdz.ch.wx.api.aes
;
import
org.junit.*
;
import
org.w3c.dom.Document
;
import
org.w3c.dom.Element
;
import
org.w3c.dom.NodeList
;
import
org.xml.sax.InputSource
;
import
org.xml.sax.SAXException
;
import
javax.xml.parsers.DocumentBuilder
;
import
javax.xml.parsers.DocumentBuilderFactory
;
import
javax.xml.parsers.ParserConfigurationException
;
import
java.io.IOException
;
import
java.io.StringReader
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
fail
;
public
class
WXBizMsgCryptTest
{
String
encodingAesKey
=
"abcdefghijklmnopqrstuvwxyz0123456789ABCDEFG"
;
String
token
=
"pamtest"
;
String
timestamp
=
"1409304348"
;
String
nonce
=
"xxxxxx"
;
String
appId
=
"wxb11529c136998cb6"
;
String
replyMsg
=
"我是中文abcd123"
;
String
xmlFormat
=
"<xml><ToUserName><![CDATA[toUser]]></ToUserName><Encrypt><![CDATA[%1$s]]></Encrypt></xml>"
;
String
afterAesEncrypt
=
"jn1L23DB+6ELqJ+6bruv21Y6MD7KeIfP82D6gU39rmkgczbWwt5+3bnyg5K55bgVtVzd832WzZGMhkP72vVOfg=="
;
String
randomStr
=
"aaaabbbbccccdddd"
;
String
replyMsg2
=
"<xml><ToUserName><![CDATA[oia2Tj我是中文jewbmiOUlr6X-1crbLOvLw]]></ToUserName><FromUserName><![CDATA[gh_7f083739789a]]></FromUserName><CreateTime>1407743423</CreateTime><MsgType><![CDATA[video]]></MsgType><Video><MediaId><![CDATA[eYJ1MbwPRJtOvIEabaxHs7TX2D-HV71s79GUxqdUkjm6Gs2Ed1KF3ulAOA9H1xG0]]></MediaId><Title><![CDATA[testCallBackReplyVideo]]></Title><Description><![CDATA[testCallBackReplyVideo]]></Description></Video></xml>"
;
String
afterAesEncrypt2
=
"jn1L23DB+6ELqJ+6bruv23M2GmYfkv0xBh2h+XTBOKVKcgDFHle6gqcZ1cZrk3e1qjPQ1F4RsLWzQRG9udbKWesxlkupqcEcW7ZQweImX9+wLMa0GaUzpkycA8+IamDBxn5loLgZpnS7fVAbExOkK5DYHBmv5tptA9tklE/fTIILHR8HLXa5nQvFb3tYPKAlHF3rtTeayNf0QuM+UW/wM9enGIDIJHF7CLHiDNAYxr+r+OrJCmPQyTy8cVWlu9iSvOHPT/77bZqJucQHQ04sq7KZI27OcqpQNSto2OdHCoTccjggX5Z9Mma0nMJBU+jLKJ38YB1fBIz+vBzsYjrTmFQ44YfeEuZ+xRTQwr92vhA9OxchWVINGC50qE/6lmkwWTwGX9wtQpsJKhP+oS7rvTY8+VdzETdfakjkwQ5/Xka042OlUb1/slTwo4RscuQ+RdxSGvDahxAJ6+EAjLt9d8igHngxIbf6YyqqROxuxqIeIch3CssH/LqRs+iAcILvApYZckqmA7FNERspKA5f8GoJ9sv8xmGvZ9Yrf57cExWtnX8aCMMaBropU/1k+hKP5LVdzbWCG0hGwx/dQudYR/eXp3P0XxjlFiy+9DMlaFExWUZQDajPkdPrEeOwofJb"
;
@BeforeClass
public
static
void
setUpBeforeClass
()
throws
Exception
{
}
@AfterClass
public
static
void
tearDownAfterClass
()
throws
Exception
{
}
@Before
public
void
setUp
()
throws
Exception
{
}
@After
public
void
tearDown
()
throws
Exception
{
}
@Test
public
void
testNormal
()
throws
ParserConfigurationException
,
SAXException
,
IOException
{
try
{
WXBizMsgCrypt
pc
=
new
WXBizMsgCrypt
(
token
,
encodingAesKey
,
appId
);
String
afterEncrpt
=
pc
.
encryptMsg
(
replyMsg
,
timestamp
,
nonce
);
DocumentBuilderFactory
dbf
=
DocumentBuilderFactory
.
newInstance
();
DocumentBuilder
db
=
dbf
.
newDocumentBuilder
();
StringReader
sr
=
new
StringReader
(
afterEncrpt
);
InputSource
is
=
new
InputSource
(
sr
);
Document
document
=
db
.
parse
(
is
);
Element
root
=
document
.
getDocumentElement
();
NodeList
nodelist1
=
root
.
getElementsByTagName
(
"Encrypt"
);
NodeList
nodelist2
=
root
.
getElementsByTagName
(
"MsgSignature"
);
String
encrypt
=
nodelist1
.
item
(
0
).
getTextContent
();
String
msgSignature
=
nodelist2
.
item
(
0
).
getTextContent
();
String
fromXML
=
String
.
format
(
xmlFormat
,
encrypt
);
// 第三方收到公众号平台发送的消息
String
afterDecrpt
=
pc
.
decryptMsg
(
msgSignature
,
timestamp
,
nonce
,
fromXML
);
assertEquals
(
replyMsg
,
afterDecrpt
);
}
catch
(
AesException
e
)
{
fail
(
"正常流程,怎么就抛出异常了??????"
);
}
}
@Test
public
void
testAesEncrypt
()
{
try
{
WXBizMsgCrypt
pc
=
new
WXBizMsgCrypt
(
token
,
encodingAesKey
,
appId
);
assertEquals
(
afterAesEncrypt
,
pc
.
encrypt
(
randomStr
,
replyMsg
));
}
catch
(
AesException
e
)
{
e
.
printStackTrace
();
fail
(
"no异常"
);
}
}
@Test
public
void
testAesEncrypt2
()
{
try
{
WXBizMsgCrypt
pc
=
new
WXBizMsgCrypt
(
token
,
encodingAesKey
,
appId
);
assertEquals
(
afterAesEncrypt2
,
pc
.
encrypt
(
randomStr
,
replyMsg2
));
}
catch
(
AesException
e
)
{
e
.
printStackTrace
();
fail
(
"no异常"
);
}
}
@Test
public
void
testIllegalAesKey
()
{
try
{
new
WXBizMsgCrypt
(
token
,
"abcde"
,
appId
);
}
catch
(
AesException
e
)
{
assertEquals
(
AesException
.
IllegalAesKey
,
e
.
getCode
());
return
;
}
fail
(
"错误流程不抛出异常???"
);
}
@Test
public
void
testValidateSignatureError
()
throws
ParserConfigurationException
,
SAXException
,
IOException
{
try
{
WXBizMsgCrypt
pc
=
new
WXBizMsgCrypt
(
token
,
encodingAesKey
,
appId
);
String
afterEncrpt
=
pc
.
encryptMsg
(
replyMsg
,
timestamp
,
nonce
);
DocumentBuilderFactory
dbf
=
DocumentBuilderFactory
.
newInstance
();
DocumentBuilder
db
=
dbf
.
newDocumentBuilder
();
StringReader
sr
=
new
StringReader
(
afterEncrpt
);
InputSource
is
=
new
InputSource
(
sr
);
Document
document
=
db
.
parse
(
is
);
Element
root
=
document
.
getDocumentElement
();
NodeList
nodelist1
=
root
.
getElementsByTagName
(
"Encrypt"
);
String
encrypt
=
nodelist1
.
item
(
0
).
getTextContent
();
String
fromXML
=
String
.
format
(
xmlFormat
,
encrypt
);
pc
.
decryptMsg
(
"12345"
,
timestamp
,
nonce
,
fromXML
);
// 这里签名错误
}
catch
(
AesException
e
)
{
assertEquals
(
AesException
.
ValidateSignatureError
,
e
.
getCode
());
return
;
}
fail
(
"错误流程不抛出异常???"
);
}
@Test
public
void
testVerifyUrl
()
throws
AesException
{
WXBizMsgCrypt
wxcpt
=
new
WXBizMsgCrypt
(
"QDG6eK"
,
"jWmYm7qr5nMoAUwZRjGtBxmz3KA1tkAj3ykkR6q2B2C"
,
"wx5823bf96d3bd56c7"
);
String
verifyMsgSig
=
"5c45ff5e21c57e6ad56bac8758b79b1d9ac89fd3"
;
String
timeStamp
=
"1409659589"
;
String
nonce
=
"263014780"
;
String
echoStr
=
"P9nAzCzyDtyTWESHep1vC5X9xho/qYX3Zpb4yKa9SKld1DsH3Iyt3tP3zNdtp+4RPcs8TgAE7OaBO+FZXvnaqQ=="
;
wxcpt
.
verifyUrl
(
verifyMsgSig
,
timeStamp
,
nonce
,
echoStr
);
// 只要不抛出异常就好
}
}
ch-wx-api/src/main/java/com/wwdz/ch/wx/api/aes/XMLParse.java
0 → 100644
View file @
ca818d19
/**
* 对公众平台发送给公众账号的消息加解密示例代码.
*
* @copyright Copyright (c) 1998-2014 Tencent Inc.
*/
// ------------------------------------------------------------------------
package
com.wwdz.ch.wx.api.aes
;
import
org.w3c.dom.Document
;
import
org.w3c.dom.Element
;
import
org.w3c.dom.NodeList
;
import
org.xml.sax.InputSource
;
import
javax.xml.parsers.DocumentBuilder
;
import
javax.xml.parsers.DocumentBuilderFactory
;
import
java.io.StringReader
;
/**
* XMLParse class
*
* 提供提取消息格式中的密文及生成回复消息格式的接口.
*/
public
class
XMLParse
{
/**
* 提取出xml数据包中的加密消息
* @param xmltext 待提取的xml字符串
* @return 提取出的加密消息字符串
* @throws AesException
*/
public
static
Object
[]
extract
(
String
xmltext
)
throws
AesException
{
Object
[]
result
=
new
Object
[
3
];
try
{
DocumentBuilderFactory
dbf
=
DocumentBuilderFactory
.
newInstance
();
DocumentBuilder
db
=
dbf
.
newDocumentBuilder
();
StringReader
sr
=
new
StringReader
(
xmltext
);
InputSource
is
=
new
InputSource
(
sr
);
Document
document
=
db
.
parse
(
is
);
Element
root
=
document
.
getDocumentElement
();
NodeList
nodelist1
=
root
.
getElementsByTagName
(
"Encrypt"
);
// NodeList nodelist2 = root.getElementsByTagName("ToUserName");
result
[
0
]
=
0
;
result
[
1
]
=
nodelist1
.
item
(
0
).
getTextContent
();
// result[2] = nodelist2.item(0).getTextContent();
return
result
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
throw
new
AesException
(
AesException
.
ParseXmlError
);
}
}
/**
* 生成xml消息
* @param encrypt 加密后的消息密文
* @param signature 安全签名
* @param timestamp 时间戳
* @param nonce 随机字符串
* @return 生成的xml字符串
*/
public
static
String
generate
(
String
encrypt
,
String
signature
,
String
timestamp
,
String
nonce
)
{
String
format
=
"<xml>\n"
+
"<Encrypt><![CDATA[%1$s]]></Encrypt>\n"
+
"<MsgSignature><![CDATA[%2$s]]></MsgSignature>\n"
+
"<TimeStamp>%3$s</TimeStamp>\n"
+
"<Nonce><![CDATA[%4$s]]></Nonce>\n"
+
"</xml>"
;
return
String
.
format
(
format
,
encrypt
,
signature
,
timestamp
,
nonce
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment