|
@@ -14,6 +14,8 @@ import javax.xml.parsers.ParserConfigurationException;
|
|
|
|
|
|
import com.google.common.base.CharMatcher;
|
|
|
import com.google.common.io.BaseEncoding;
|
|
|
+import lombok.AllArgsConstructor;
|
|
|
+import lombok.Data;
|
|
|
import me.chanjar.weixin.common.error.WxRuntimeException;
|
|
|
import org.apache.commons.codec.binary.Base64;
|
|
|
import org.w3c.dom.Document;
|
|
@@ -158,6 +160,29 @@ public class WxCryptUtil {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
+ * 将公众平台回复用户的消息加密打包.
|
|
|
+ * <ol>
|
|
|
+ * <li>对要发送的消息进行AES-CBC加密</li>
|
|
|
+ * <li>生成安全签名</li>
|
|
|
+ * <li>将消息密文和安全签名打包成xml格式</li>
|
|
|
+ * </ol>
|
|
|
+ *
|
|
|
+ * @param plainText 公众平台待回复用户的消息,xml格式的字符串
|
|
|
+ * @return 加密消息所需的值对象
|
|
|
+ */
|
|
|
+ public EncryptContext encryptContext(String plainText) {
|
|
|
+ // 加密
|
|
|
+ String encryptedXml = encrypt(genRandomStr(), plainText);
|
|
|
+
|
|
|
+ // 生成安全签名
|
|
|
+ String timeStamp = Long.toString(System.currentTimeMillis() / 1000L);
|
|
|
+ String nonce = genRandomStr();
|
|
|
+
|
|
|
+ String signature = SHA1.gen(this.token, timeStamp, nonce, encryptedXml);
|
|
|
+ return new EncryptContext(encryptedXml, signature, timeStamp, nonce);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
* 对明文进行加密.
|
|
|
*
|
|
|
* @param plainText 需要加密的明文
|
|
@@ -211,22 +236,56 @@ public class WxCryptUtil {
|
|
|
* @param msgSignature 签名串,对应URL参数的msg_signature
|
|
|
* @param timeStamp 时间戳,对应URL参数的timestamp
|
|
|
* @param nonce 随机串,对应URL参数的nonce
|
|
|
- * @param encryptedXml 密文,对应POST请求的数据
|
|
|
+ * @param encryptedXml 包含 Encrypt 密文的 xml,对应POST请求的数据
|
|
|
* @return 解密后的原文
|
|
|
*/
|
|
|
- public String decrypt(String msgSignature, String timeStamp, String nonce, String encryptedXml) {
|
|
|
+ public String decryptXml(String msgSignature, String timeStamp, String nonce, String encryptedXml) {
|
|
|
// 密钥,公众账号的app corpSecret
|
|
|
// 提取密文
|
|
|
String cipherText = extractEncryptPart(encryptedXml);
|
|
|
+ return decryptContent(msgSignature, timeStamp, nonce, cipherText);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检验消息的真实性,并且获取解密后的明文.
|
|
|
+ * <ol>
|
|
|
+ * <li>利用收到的密文生成安全签名,进行签名验证</li>
|
|
|
+ * <li>若验证通过,则提取xml中的加密消息</li>
|
|
|
+ * <li>对消息进行解密</li>
|
|
|
+ * </ol>
|
|
|
+ *
|
|
|
+ * @param msgSignature 签名串,对应URL参数的msg_signature
|
|
|
+ * @param timeStamp 时间戳,对应URL参数的timestamp
|
|
|
+ * @param nonce 随机串,对应URL参数的nonce
|
|
|
+ * @param encryptedXml 包含 Encrypt 密文的 xml,对应POST请求的数据
|
|
|
+ * @return 解密后的原文
|
|
|
+ */
|
|
|
+ public String decrypt(String msgSignature, String timeStamp, String nonce, String encryptedXml) {
|
|
|
+ return decryptXml(msgSignature, timeStamp, nonce, encryptedXml);
|
|
|
+ }
|
|
|
|
|
|
+ /**
|
|
|
+ * 检验消息的真实性,并且获取解密后的明文.
|
|
|
+ * <ol>
|
|
|
+ * <li>利用收到的密文生成安全签名,进行签名验证</li>
|
|
|
+ * <li>若验证通过,则提取xml中的加密消息</li>
|
|
|
+ * <li>对消息进行解密</li>
|
|
|
+ * </ol>
|
|
|
+ *
|
|
|
+ * @param msgSignature 签名串,对应URL参数的msg_signature
|
|
|
+ * @param timeStamp 时间戳,对应URL参数的timestamp
|
|
|
+ * @param nonce 随机串,对应URL参数的nonce
|
|
|
+ * @param encryptedContent 加密文本体
|
|
|
+ * @return 解密后的原文
|
|
|
+ */
|
|
|
+ public String decryptContent(String msgSignature, String timeStamp, String nonce, String encryptedContent) {
|
|
|
// 验证安全签名
|
|
|
- String signature = SHA1.gen(this.token, timeStamp, nonce, cipherText);
|
|
|
+ String signature = SHA1.gen(this.token, timeStamp, nonce, encryptedContent);
|
|
|
if (!signature.equals(msgSignature)) {
|
|
|
throw new WxRuntimeException("加密消息签名校验失败");
|
|
|
}
|
|
|
-
|
|
|
// 解密
|
|
|
- return decrypt(cipherText);
|
|
|
+ return decrypt(encryptedContent);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -271,12 +330,20 @@ public class WxCryptUtil {
|
|
|
}
|
|
|
|
|
|
// appid不相同的情况 暂时忽略这段判断
|
|
|
-// if (!fromAppid.equals(this.appidOrCorpid)) {
|
|
|
-// throw new WxRuntimeException("AppID不正确,请核实!");
|
|
|
-// }
|
|
|
+ // if (!fromAppid.equals(this.appidOrCorpid)) {
|
|
|
+ // throw new WxRuntimeException("AppID不正确,请核实!");
|
|
|
+ // }
|
|
|
|
|
|
return xmlContent;
|
|
|
|
|
|
}
|
|
|
|
|
|
+ @Data
|
|
|
+ @AllArgsConstructor
|
|
|
+ public static class EncryptContext {
|
|
|
+ private String encrypt;
|
|
|
+ private String signature;
|
|
|
+ private String timeStamp;
|
|
|
+ private String nonce;
|
|
|
+ }
|
|
|
}
|