Aspose Office 的应用

注意:笔者使用的aspose office 的 jar 包版本 : 18.6(aspose-XXX-18.8-java)

--------------------------------------------------------------------------------------------------------------

使用到的工具 : jd-gui.exe --- Java反编译工具。

        javassist --- Java动态编程。

    

<dependency>
    <groupId>javassist</groupId>
    <artifactId>javassist</artifactId>
    <version>3.12.1.GA</version>
</dependency>
               

应用思路 : 先找到 License 类,再找到 License 中 setLicense( ) 方法 调用的 关键类 ( 就是用于加密的类 ) ,然后利用 javassist 技术 修改 加密类里的 加密方法

---------------------------------------------------------------------------------------------------------

jar处理

aspose-words-18.8-jdk16.jar

 License 类的方法

    //我们调用的是这个方法进行加密验证的
    //此方法主要是调用 zzZLR 对象的 zzX( ) 方法进行加密验证的。
    public void setLicense(InputStream stream) throws Exception {
        if (stream == null) {
            throw new NullPointerException("stream");
        }
        zzZLR zzZLR;
        (zzZLR = new zzZLR()).zzX(stream);
    }
    
    public void setLicense(String licenseName) throws Exception {
        if (licenseName == null) {
            throw new NullPointerException("licenseName");
        }
        
        zzZLR zzZLR;
        (zzZLR = new zzZLR()).zzY(licenseName, zz2R.zzzS());
    }
zzZLR类的关键方法 : (要找到与加密相关的方法)
  private static void zzZ(Node paramNode1, Node paramNode2) throws Exception {
        byte[] arrayOfByte2;
        byte[] arrayOfByte1;
        if (paramNode1 != null) {
          zzZ(arrayOfByte2 = new StringBuilder(), paramNode1);
          arrayOfByte1 = arrayOfByte2.toString().getBytes("UTF-16LE");
        } else {
          arrayOfByte1 = new byte[0];
        } 
        if (paramNode2 != null) {
          String str1, str2;
          arrayOfByte2 = zz30.decode(str2 = str1 = paramNode2.getFirstChild().getNodeValue());
        } else {
          arrayOfByte2 = new byte[0];
        } 
        try {
          zzZ(arrayOfByte1, arrayOfByte2, "0nRuwNEddXwLfXB7pw66G71MS93gW8mNzJ7vuh3Sf4VAEOBfpxtHLCotymv1PoeukxYe31K441Ivq0Pkvx1yZZG4O1KCv3Omdbs7uqzUB4xXHlOub4VsTODzDJ5MWHqlRCB1HHcGjlyT2sVGiovLt0Grvqw5+QXBuinoBY0suX0=", "SHA1withRSA");
          return;
        } catch (Exception exception) {
          zzZ(arrayOfByte1, arrayOfByte2, "3ki45T6C4lt12J5MbKfrADBCZcE8OTefdngc9IDKg+lzCGYLuxJFDt16awhJFnA23sX+kQ4/eZQ5pNAYjc+ZJ0+pWwvQR4h8GJ3eWvecdFs7KSWwNmFXZCSN+sbrxwEjzzns1kIHuLNf5r+Zaggns+8rqXR19RSJBOcuFqVipIHv56lF53Hc+hx+y9URIaadO1W8dkTqgwExyfjnbDOaCBEH0CqUL1YIICS/wIUTEKhM0ZlwEcIcHl8XTHLVx96DMX4bbVajj78L4KzevQc442DX28KGDJTveEB1pSKWsr0d4FTx7wKS36RBnWv5lwsRErtTZb5ciVIG1iIJrp87VQ==", "SHA256withRSA");
          return;
        } 
    }
    
    /*
     * 这是关键方法,涉及到加密内容的 ;使用的是JDK的 KeyFactory类进行加密的,采用的算法是  RSA
     * 【注意】 :这就是我们要修改的地方
     */
    private static void zzZ(byte[] paramArrayOfByte1, byte[] paramArrayOfByte2, String paramString1, String paramString2) throws Exception {
        Signature signature = Signature.getInstance(paramString2);
        String str3 = "AQAB";
        String str1, str2, str4;
        byte[] arrayOfByte1 =  zz30.decode(str4 = str2 = str1 = paramString1);
        byte[] arrayOfByte2 = zz30.decode(str4 = str3);
        arrayOfByte1 = zzZg(arrayOfByte1);
        arrayOfByte2 = zzZg(arrayOfByte2);
        BigInteger bigInteger1 = new BigInteger(1, arrayOfByte1);
        BigInteger bigInteger2 = new BigInteger(1, arrayOfByte2);
        RSAPublicKeySpec rSAPublicKeySpec = new RSAPublicKeySpec(bigInteger1, bigInteger2);
        PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(rSAPublicKeySpec);
        signature.initVerify(publicKey);
        signature.update(paramArrayOfByte1);
        if (!signature.verify(paramArrayOfByte2)) {
          throw new IllegalStateException("The signature is invalid.");
        }
    }
    
    private static String zzZ(Element paramElement, String paramString) {
        Element element;
        return ((element = zzX(paramElement, paramString)) != null) ? element.getFirstChild().getNodeValue() : "";
    }
    
    private static void zzZ(StringBuilder paramStringBuilder, Node paramNode) {
        if (paramNode.getNodeType() == 1) {
          paramStringBuilder.append('<');
          paramStringBuilder.append(paramNode.getNodeName());
          paramStringBuilder.append('>');
          NodeList nodeList1, nodeList2;
          Node node;
          if (((nodeList2 = nodeList1 = paramNode.getChildNodes()) != null && nodeList2.getLength() == 1 && (node = nodeList2.item(false)) != null && node.getNodeType() == 3)) {
            Node node1;
            String str = (str = (str = (str = (node1 = nodeList1.item(0)).getNodeValue()).replace("&", "&amp;")).replace("<", "&lt;")).replace(">", "&gt;");
            paramStringBuilder.append(str);
          } else {
            for (byte b = 0; b < nodeList1.getLength(); b++)
              zzZ(paramStringBuilder, nodeList1.item(b)); 
          } 
          paramStringBuilder.append('<');
          paramStringBuilder.append('/');
          paramStringBuilder.append(paramNode.getNodeName());
          paramStringBuilder.append('>');
        } 
    }

修改 zzZLR 的 zzZ(byte[] paramArrayOfByte1, byte[] paramArrayOfByte2, String paramString1, String paramString2)方法。

  @Test
    public  void changeMethod() throws Exception {
        ClassPool.getDefault().insertClassPath( "E:/18.8/aspose-words-18.8-java/lib/aspose-words-18.8-jdk16.jar");
        CtClass c2 = ClassPool.getDefault().getCtClass("com.aspose.words.zzZLR");
        CtMethod[] ms = c2.getDeclaredMethods();
        for (CtMethod c : ms) {
//            System.out.println(c.getName());
            CtClass[] ps = c.getParameterTypes();
            
//            for (CtClass cx : ps) { System.out.println("	" + cx.getName()); }
            
            if (c.getName().equals("zzZ") && ps.length == 4 ) {
                c.insertBefore("{return;}");//替换整个方法体。
            }
            
//            if (c.getName().equals("zzZ") && ps.length == 2 && ps[0].getName().equals("org.w3c.dom.Node") && ps[1].getName().equals("org.w3c.dom.Node")) {
//                c.insertBefore("{return;}"); }
 
        }
//        c2.writeFile();//写到原文件里
        c2.writeFile("E:/18.8");//把重写的 zzZ 类写到指定的目录下
    }

用解压工具(zip)查看 aspose-words-18.8-jdk16.jar ,

  然后用新生成的 zzZ类 替换jar文件里原来 zzZ类;

  把jar文件里的删除jar文件中的 META-INF文件夹删掉( 防止文件指纹校验 )

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

aspose-cells-18.8.jar

要修改的关键方法(License 类的方法 )

  /*
     *  这就加密关键所在
     *  JDK加密关键类和词 :KeyFactory  Signature  RSAPublicKeySpec  ,采用的算法是RSA
     * 
     */
    private static boolean a(String paramString1, String paramString2) {
        if (paramString1.equals(zj.a(new byte[] { 
                -93, -121, -74, 46, 120, 126, -63, 125, -97, -20, 
                -27, -44, 61, -47, -83, -94, 93, -67 }))) {
          paramString1 = zj.a(new byte[] { 
                108, 19, -21, 22, -117, 126, 124, 3, -35, -84, 
                -108, -94, -125, -104, -75, -68, 10, 93, -106, 45, 
                98, 0, 30, -67, -67 });
        } else {
          paramString1 = paramString1.replaceAll(zj.a(new byte[] { -90, -102, -13, 40, 105, 1, -111, 125 }, ), zj.a(new byte[] { -124, 124, -114, -35, -53, -118, 2, -112, -3, -67 }));
        } 
        PublicKey publicKey = null;
        try {
          KeyFactory keyFactory = KeyFactory.getInstance(zj.a(new byte[] { 32, 37, -48, -122, -114, -96, -69, 49, 61, -67 }));
          RSAPublicKeySpec rSAPublicKeySpec = new RSAPublicKeySpec(new BigInteger(1, zcq.a(h, zj.a(new byte[] { 72, 3, -106, -46, -7, 81, 61, -27, -67 }))), new BigInteger(1, zcq.a(i, zj.a(new byte[] { 
                      -13, -24, 23, 17, -26, 42, 67, -72, -48, 85, 
                      32, 45, -74, -67 }))));
          publicKey = keyFactory.generatePublic(rSAPublicKeySpec);
          Signature signature = null;
          byte[] arrayOfByte1 = null;
          byte[] arrayOfByte2 = paramString1.getBytes(zj.a(new byte[] { 
                  -104, -23, 14, -59, -2, -46, -7, 81, 61, -100, 
                  -110, 13, -67 }));
          arrayOfByte1 = zcq.a(paramString2, zj.a(new byte[] { 
                  103, 36, 50, 8, 122, -15, -21, 99, 52, 100, 
                  -67, 13, -67 }));
          signature = Signature.getInstance(zj.a(new byte[] { 
                  -23, 106, 106, -106, -116, 102, 44, 122, 52, -55, 
                  -67, -120, -10, 40, -59, 43, -67, -83, 109, -3 }));
          signature.initVerify(publicKey);
          signature.update(arrayOfByte2);
          if (!signature.verify(arrayOfByte1)) {
            rSAPublicKeySpec = new RSAPublicKeySpec(new BigInteger(1, zcq.a(j, zj.a(new byte[] { 
                        25, -72, 38, -51, -88, 10, 31, -53, -3, -111, 
                        -67 }))), new BigInteger(1, zcq.a(i, zj.a(new byte[] { 
                        90, 106, 71, 98, -73, 102, 108, -122, -99, -85, 
                        -67 }))));
            publicKey = keyFactory.generatePublic(rSAPublicKeySpec);
            signature = Signature.getInstance(zj.a(new byte[] { 
                    124, -56, 11, 15, 14, 119, -91, -99, 62, -124, 
                    -51, 17, -59, -68, 53, -41, 42, -105, 76, -111, 
                    -67, -100, 29, 61 }));
            signature.initVerify(publicKey);
            signature.update(arrayOfByte2);
            if (!signature.verify(arrayOfByte1))
              return false; 
          } 
        } catch (Exception exception) {
          return false;
        } 
        return true;
    }

修改关键方法

  @Test
    public  void changeMethod() throws Exception {
        ClassPool.getDefault().insertClassPath( "E:/18.8/aspose-cells-18.8-java/JDK 1.6/aspose-cells-18.8-java/lib/aspose-cells-18.8.jar");
        CtClass c2 = ClassPool.getDefault().getCtClass("com.aspose.cells.License");
        CtMethod[] ms = c2.getDeclaredMethods();
        for (CtMethod c : ms) {
//            System.out.println(c.getName());
            CtClass[] ps = c.getParameterTypes();
            
//            for (CtClass cx : ps) { System.out.println("	" + cx.getName()); }
            
            if (c.getName().equals("a") && ps.length == 2 &&
                    ps[0].getName().equals("java.lang.String") && ps[1].getName().equals("java.lang.String")) {
                c.insertBefore("{return true;}");//替换整个方法体。
            }
            
//            if (c.getName().equals("zzZ") && ps.length == 2 && ps[0].getName().equals("org.w3c.dom.Node") && ps[1].getName().equals("org.w3c.dom.Node")) {
//                c.insertBefore("{return;}"); }
        }
//        c2.writeFile();//写到原文件里
        c2.writeFile("E:/18.8");//把重写的 zzZ 类写到指定的目录下
    }

然后就是替换类,删除META-INF文件夹。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

aspose-slides-18.8-jdk16.jar

关键方法:(com.aspose.slides.internal.k5.return类的方法)

   /*
     *  这就加密关键所在
     *  JDK加密关键类和词 :KeyFactory  Signature  RSAPublicKeySpec  ,采用的算法是RSA
     */
    private static void do(Node paramNode1, Node paramNode2) {
        PublicKey publicKey = null;
        try {
          KeyFactory keyFactory = KeyFactory.getInstance("RSA");
          RSAPublicKeySpec rSAPublicKeySpec = void.do();
          publicKey = keyFactory.generatePublic(rSAPublicKeySpec);
        } catch (Exception exception) {
          (new float() {
            
            }).do((new throws() {
              
              },  ).if, exception);
        } 
        try {
          String str1 = (paramNode1 != null) ? do(paramNode1) : "";
          byte[] arrayOfByte1 = str1.getBytes("UTF-16LE");
          String str2 = (paramNode2 != null) ? paramNode2.getFirstChild().getNodeValue() : "";
          byte[] arrayOfByte2 = try.do(str2);
          Signature signature = Signature.getInstance("SHA1withRSA");
          signature.initVerify(publicKey);
          signature.update(arrayOfByte1);
          if (!signature.verify(arrayOfByte2))
            (new float() {
              
              }).do((new throws() {
                
                }).for); 
        } catch (Exception exception) {
          (new float() {
            
            }).do((new throws() {
              
              },  ).int, exception);
        } 
    }

修改关键方法

@Test
public  void changeMethod() throws Exception {
       ............
      if (c.getName().equals("do") && ps.length == 2 &&                             
          ps[0].getName().equals("org.w3c.dom.Node") &&  ps[1].getName().equals("org.w3c.dom.Node")) {
       c.insertBefore("{return;}"); 
    }
     .............
}

然后就是替换类,删除META-INF文件夹。

到此,word , excel , ppt 的 jar处理完毕

-------------------------------------------------------------------------------------------

以下是具体的代码。 

aspose office 的监听文件,放在项目类路径下 :

<?xml version="1.0" encoding="UTF-8"?>
<License>
  <Data>
    <Products>
      <Product>Aspose.Words for Java</Product>
      <Product>Aspose.Slides for Java</Product>
      <Product>Aspose.Cells for Java</Product>
    </Products>
    <EditionType>Enterprise</EditionType>
    <SubscriptionExpiry>29991231</SubscriptionExpiry>
    <LicenseExpiry>29991231</LicenseExpiry>
    <SerialNumber>---</SerialNumber>
  </Data>
  <Signature>---</Signature>
</License>

aspose office 操作工具类

public abstract class AsposeOfficeUtil {
    /**
     * 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换
     * @param from   
     * @param to    
     * @throws Exception
     */
    public static String word(String from,String to) throws Exception  {            
        if (!getWordLicense())   throw new Exception("com.aspose.words lic ERROR!");
        File file = new File(to);  //新建一个空白pdf文档
        try {
            long old = System.currentTimeMillis();
            
            FileOutputStream os = new FileOutputStream(file);
            Document doc = new Document(from);                    //Address是将要被转化的word文档
            doc.save(os, com.aspose.words.SaveFormat.PDF);//全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换
            long now = System.currentTimeMillis();
            System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒");  //转化用时
           
        } catch (Exception e) {
            e.printStackTrace();
        }
        //return file.getName();
        return file.getPath();
    }
    
    public static String excel(String form,String to) throws Exception {
        if (!getExcelLicense())   throw new Exception("com.aspose.words lic ERROR!");
        File file = new File(to);// 输出路径
        try {
            long old = System.currentTimeMillis();
            
            Workbook wb = new Workbook(form);// 原始excel路径
            FileOutputStream fileOS = new FileOutputStream(file);
            wb.save(fileOS,com.aspose.cells.SaveFormat.PDF);
            fileOS.close();
            long now = System.currentTimeMillis();
            System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒

" + "文件保存在:" + file.getPath()); //转化过程耗时
            
        } catch (Exception e) {
            e.printStackTrace();
        }
        //return file.getName();
        return file.getPath();
    }
    
    public static String ppt(String form,String to) throws Exception {
        // 验证License
        if (!getPPTLicense())  throw new Exception("com.aspose.words lic ERROR!");
        File file = new File(to);// 输出pdf路径
        try {
            long old = System.currentTimeMillis();
            
            Presentation pres = new Presentation(form);//输入pdf路径
            FileOutputStream fileOS = new FileOutputStream(file);
            pres.save(fileOS, com.aspose.slides.SaveFormat.Pdf);
            fileOS.close();
            long now = System.currentTimeMillis();
            System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒

" + "文件保存在:" + file.getPath()); //转化过程耗时
            
         } catch (Exception e) {
             e.printStackTrace();
         }
        //return file.getName();
        return file.getPath();
    }
    
    private static boolean getWordLicense(){
        boolean result = false;
        try {
            InputStream is =AsposeOfficeUtil.class.getClassLoader().getResourceAsStream("license.xml");  
            com.aspose.words.License aposeLic = new com.aspose.words.License();
            aposeLic.setLicense(is);
            result = true;
        } catch (Exception e) {
            
        }
        return result;
    }
    
    private static boolean getExcelLicense(){
        boolean result = false;
        try {
            InputStream is =AsposeOfficeUtil.class.getClassLoader().getResourceAsStream("license.xml");  
            com.aspose.cells.License aposeLic = new com.aspose.cells.License();
            aposeLic.setLicense(is);
            result = true;
        } catch (Exception e) {
            
        }
        return result;
    }
    
    private static boolean getPPTLicense(){
        boolean result = false;
        try {
            InputStream is =AsposeOfficeUtil.class.getClassLoader().getResourceAsStream("license.xml");  
            com.aspose.slides.License aposeLic = new com.aspose.slides.License();
            aposeLic.setLicense(is);
            result = true;
        } catch (Exception e) {
            
        }
        return result;
    }
    public static void main(String[] args) throws Exception {
//        System.out.println(getWordLicense());
//        System.out.println(getExcelLicense());
//        System.out.println(getPPTLicense());
//        word("E:/office/wdp.docx", "E:/office/pdf/docx2pdf.pdf");
//        word("E:/office/wdp2.doc", "E:/office/pdf/doc2pdf.pdf");
//        excel("E:/office/wdp.xlsx", "E:/office/pdf/xlsx2pdf.pdf");
//        excel("E:/office/wdp2.xls", "E:/office/pdf/xls2pdf.pdf");
//        ppt("E:/office/wdp.pptx", "E:/office/pdf/pptx2pdf.pdf");
//        ppt("E:/office/wdp2.ppt", "E:/office/pdf/ppt2pdf.pdf");
    }
}
View Code

注意 ;com.aspose.XXX.SaveFormat.XXX ,不只是pdf,还有很多类型  html svg odp 等。

资源路径 : https://pan.baidu.com/s/1HBuLI7n8vV5CjQwpzhLNiw

 

原文地址:https://www.cnblogs.com/wdp1990/p/11459224.html