注意:笔者使用的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("&", "&")).replace("<", "<")).replace(">", ">"); 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("\t" + 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("\t" + 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) + "秒\n\n" + "文件保存在:" + 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) + "秒\n\n" + "文件保存在:" + 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");
}
}
注意 ;com.aspose.XXX.SaveFormat.XXX ,不只是pdf,还有很多类型 html svg odp 等。
资源路径 : https://pan.baidu.com/s/1HBuLI7n8vV5CjQwpzhLNiw