Explorar el Código

:art: 增加对象自身的解密方法,调整解密工具类方法名

Scruel Tao hace 3 años
padre
commit
1c6b7fc07c

+ 75 - 8
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/WxCryptUtil.java

@@ -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;
+  }
 }

+ 14 - 1
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlMessage.java

@@ -506,7 +506,6 @@ public class WxMpXmlMessage implements Serializable {
   @JacksonXmlProperty(localName = "ReceiptInfo")
   private String receiptInfo;
 
-
   ///////////////////////////////////////
   // 门店审核事件推送
   ///////////////////////////////////////
@@ -797,6 +796,12 @@ public class WxMpXmlMessage implements Serializable {
   @JacksonXmlProperty(localName = "nsrsbh")
   private String nsrsbh;
 
+  /**
+   * 加密消息
+   */
+  @XStreamAlias("Encrypt")
+  @JacksonXmlProperty(localName = "Encrypt")
+  private String encrypt;
 
   public static WxMpXmlMessage fromXml(String xml) {
     //修改微信变态的消息内容格式,方便解析
@@ -836,6 +841,14 @@ public class WxMpXmlMessage implements Serializable {
     }
   }
 
+  public WxMpXmlMessage decryptField(WxMpConfigStorage wxMpConfigStorage,
+                                     String timestamp, String nonce, String msgSignature) {
+    WxMpCryptUtil cryptUtil = new WxMpCryptUtil(wxMpConfigStorage);
+    String plainText = cryptUtil.decryptContent(msgSignature, timestamp, nonce, this.encrypt);
+    log.debug("解密后的原始xml消息内容:{}", plainText);
+    return fromXml(plainText);
+  }
+
   /**
    * <pre>
    * 当接受用户消息时,可能会获得以下值: