Example #1
0
  /**
   * 对密文进行解密.
   *
   * @param text 需要解密的密文
   * @return 解密得到的明文
   * @throws AesException aes解密失败
   */
  String decrypt(String text) throws AesException {
    byte[] original;
    try {
      // 设置解密模式为AES的CBC模式
      Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
      SecretKeySpec key_spec = new SecretKeySpec(aesKey, "AES");
      IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16));
      cipher.init(Cipher.DECRYPT_MODE, key_spec, iv);

      // 使用BASE64对密文进行解码
      byte[] encrypted = Base64.decodeBase64(text);

      // 解密
      original = cipher.doFinal(encrypted);
    } catch (Exception e) {
      e.printStackTrace();
      throw new AesException(AesException.DecryptAESError);
    }

    String xmlContent, from_appid;
    try {
      // 去除补位字符
      byte[] bytes = PKCS7Encoder.decode(original);

      // 分离16位随机字符串,网络字节序和AppId
      byte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20);

      int xmlLength = recoverNetworkBytesOrder(networkOrder);

      xmlContent = new String(Arrays.copyOfRange(bytes, 20, 20 + xmlLength), CHARSET);
      from_appid = new String(Arrays.copyOfRange(bytes, 20 + xmlLength, bytes.length), CHARSET);
    } catch (Exception e) {
      e.printStackTrace();
      throw new AesException(AesException.IllegalBuffer);
    }

    // appid不相同的情况
    if (!from_appid.equals(appId)) {
      throw new AesException(AesException.ValidateAppidError);
    }
    return xmlContent;
  }
Example #2
0
 /**
  * 对AES消息解密
  *
  * @param appId
  * @param encodingAesKey aes加密的密钥
  * @param encryptContent 加密的消息体
  * @return 解密后的字符
  * @throws WeixinException
  */
 public static String aesDecrypt(String appId, String encodingAesKey, String encryptContent)
     throws WeixinException {
   byte[] aesKey = Base64.decodeBase64(encodingAesKey + "=");
   byte[] original;
   try {
     // 设置解密模式为AES的CBC模式
     Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
     SecretKeySpec key_spec = new SecretKeySpec(aesKey, Consts.AES);
     IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16));
     cipher.init(Cipher.DECRYPT_MODE, key_spec, iv);
     // 使用BASE64对密文进行解码
     byte[] encrypted = Base64.decodeBase64(encryptContent);
     // 解密
     original = cipher.doFinal(encrypted);
   } catch (Exception e) {
     throw new WeixinException("-40007", "AES解密失败" + e.getMessage());
   }
   String xmlContent, fromAppId;
   try {
     // 去除补位字符
     byte[] bytes = PKCS7Encoder.decode(original);
     // 获取表示xml长度的字节数组
     byte[] lengthByte = Arrays.copyOfRange(bytes, 16, 20);
     // 获取xml消息主体的长度(byte[]2int)
     // http://my.oschina.net/u/169390/blog/97495
     int xmlLength =
         lengthByte[3] & 0xff
             | (lengthByte[2] & 0xff) << 8
             | (lengthByte[1] & 0xff) << 16
             | (lengthByte[0] & 0xff) << 24;
     xmlContent = StringUtil.newStringUtf8(Arrays.copyOfRange(bytes, 20, 20 + xmlLength));
     fromAppId = StringUtil.newStringUtf8(Arrays.copyOfRange(bytes, 20 + xmlLength, bytes.length));
   } catch (Exception e) {
     throw new WeixinException("-40008", "xml内容不合法" + e.getMessage());
   }
   // 校验appId是否一致
   if (!fromAppId.trim().equals(appId)) {
     throw new WeixinException(
         "-40005", "校验AppID失败,expect " + appId + ",but actual is " + fromAppId);
   }
   return xmlContent;
 }