diff --git a/src/main/java/chanjarster/weixin/api/WxService.java b/src/main/java/chanjarster/weixin/api/WxService.java index 6300310ff..48588a72a 100644 --- a/src/main/java/chanjarster/weixin/api/WxService.java +++ b/src/main/java/chanjarster/weixin/api/WxService.java @@ -9,6 +9,18 @@ import chanjarster.weixin.exception.WxErrorException; */ public interface WxService { + /** + *
+ * 验证推送过来的消息的正确性 + * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=接入指南 + *+ * @param timestamp + * @param nonce + * @param signature + * @return + */ + public boolean checkSignature(String timestamp, String nonce, String signature); + /** *
* 获取access_token,本方法线程安全
diff --git a/src/main/java/chanjarster/weixin/api/WxServiceImpl.java b/src/main/java/chanjarster/weixin/api/WxServiceImpl.java
index 1c203ef4a..27debf4eb 100644
--- a/src/main/java/chanjarster/weixin/api/WxServiceImpl.java
+++ b/src/main/java/chanjarster/weixin/api/WxServiceImpl.java
@@ -1,6 +1,8 @@
package chanjarster.weixin.api;
import java.io.IOException;
+import java.security.MessageDigest;
+import java.util.Arrays;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.commons.lang3.StringUtils;
@@ -35,6 +37,35 @@ public class WxServiceImpl implements WxService {
protected WxConfigStorage wxConfigProvider;
+ public boolean checkSignature(String timestamp, String nonce, String signature) {
+ try {
+ String token = wxConfigProvider.getToken();
+ MessageDigest sha1 = MessageDigest.getInstance("SHA1");
+ String[] arr = new String[] { token, timestamp, nonce };
+ Arrays.sort(arr);
+ StringBuilder sb = new StringBuilder();
+ for(String a : arr) {
+ sb.append(a);
+ }
+ sha1.update(sb.toString().getBytes());
+ byte[] output = sha1.digest();
+ return bytesToHex(output).equals(signature);
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ protected static String bytesToHex(byte[] b) {
+ char hexDigit[] = {'0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+ StringBuffer buf = new StringBuffer();
+ for (int j = 0; j < b.length; j++) {
+ buf.append(hexDigit[(b[j] >> 4) & 0x0f]);
+ buf.append(hexDigit[b[j] & 0x0f]);
+ }
+ return buf.toString();
+ }
+
public void refreshAccessToken() throws WxErrorException {
if (!GLOBAL_ACCESS_TOKEN_REFRESH_FLAG.getAndSet(true)) {
try {
diff --git a/src/test/java/chanjarster/weixin/api/WxServiceTest.java b/src/test/java/chanjarster/weixin/api/WxServiceTest.java
index 58650bee9..a9290c18b 100644
--- a/src/test/java/chanjarster/weixin/api/WxServiceTest.java
+++ b/src/test/java/chanjarster/weixin/api/WxServiceTest.java
@@ -69,6 +69,14 @@ public class WxServiceTest {
wxService.deleteMenu();
}
+ @Test
+ public void testCheckSignature() throws WxErrorException {
+ String timestamp = "23234235423246";
+ String nonce = "y7didfkcmvnbd90sdofjkiefhsd";
+ String signature = "77b6651628dfb9a64bfb0d3432ee053ac566a459";
+ Assert.assertTrue(wxService.checkSignature(timestamp, nonce, signature));
+ }
+
@DataProvider(name="menu")
public Object[][] getMenu() throws JAXBException {
WxMenu menu = new WxMenu();
@@ -116,7 +124,6 @@ public class WxServiceTest {
}
-
@XmlRootElement(name = "xml")
@XmlAccessorType(XmlAccessType.FIELD)
public static class WxXmlConfigStorage extends WxInMemoryConfigStorage {