官网下载好需要aspose-words的版本jar包,版本不同只是校验许可的方法名不一样
一、创建一个license.xml
放src下
<License>
<Data>
<Products>
<Product>Aspose.Total for Java</Product>
<Product>Aspose.Words for Java</Product>
</Products>
<EditionType>Enterprise</EditionType>
<SubscriptionExpiry>20991231</SubscriptionExpiry>
<LicenseExpiry>20991231</LicenseExpiry>
<SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber>
</Data>
<Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature>
</License>
三、words转pdf代码
package cn.kiion.aspose.util;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import com.aspose.words.Document;
import com.aspose.words.License;
/**
* @author ZCF
*/
public class Word2PdfUtil {
public static void main(String[] args) {
wordConverterToPdf("C:\\Users\\zcf\\Desktop\\test.docx", "C:\\Users\\zcf\\Desktop\\test.pdf");
}
private static boolean getLicense() {
boolean result = false;
try {
InputStream is = Word2PdfUtil.class.getClassLoader()
.getResourceAsStream("license.xml");
License license = new License();
license.setLicense(is);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
public static void wordConverterToPdf(String wordPath, String pdfPath) {
// 验证License 若不验证则转化出的pdf文档会有水印产生
if (!getLicense()) {
return;
}
try {
long old = System.currentTimeMillis();
// 新建一个pdf文档
File file = new File(pdfPath);
FileOutputStream os = new FileOutputStream(file);
// Address是将要被转化的word文档
Document doc = new Document(wordPath);
// 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换
doc.save(os, com.aspose.words.SaveFormat.PDF);
long now = System.currentTimeMillis();
os.close();
//转化用时
System.out.println("word turn to pdf token:" + ((now - old) / 1000.0) + "s");
} catch (Exception e) {
e.printStackTrace();
}
}
}
四、执行代码
会抛出异常,跟踪代码发现是 com.aspose.words.zzZLX 类的 zzZ 方法抛出的异常
定位到抛出异常的方法
private static void zzZ(Node var0, Node var1) throws Exception {
byte[] var2;
if (var0 != null) {
StringBuilder var3;
zzZ(var3 = new StringBuilder(), var0);
var2 = var3.toString().getBytes("UTF-16LE");
} else {
var2 = new byte[0];
}
byte[] var14;
if (var1 != null) {
var14 = zz35.decode(var1.getFirstChild().getNodeValue());
} else {
var14 = new byte[0];
}
Signature var4 = Signature.getInstance("SHA1withRSA");
String var7 = "AQAB";
String var6 = "0nRuwNEddXwLfXB7pw66G71MS93gW8mNzJ7vuh3Sf4VAEOBfpxtHLCotymv1PoeukxYe31K441Ivq0Pkvx1yZZG4O1KCv3Omdbs7uqzUB4xXHlOub4VsTODzDJ5MWHqlRCB1HHcGjlyT2sVGiovLt0Grvqw5+QXBuinoBY0suX0=";
String var13 = "0nRuwNEddXwLfXB7pw66G71MS93gW8mNzJ7vuh3Sf4VAEOBfpxtHLCotymv1PoeukxYe31K441Ivq0Pkvx1yZZG4O1KCv3Omdbs7uqzUB4xXHlOub4VsTODzDJ5MWHqlRCB1HHcGjlyT2sVGiovLt0Grvqw5+QXBuinoBY0suX0=";
byte[] var8 = zz35.decode("0nRuwNEddXwLfXB7pw66G71MS93gW8mNzJ7vuh3Sf4VAEOBfpxtHLCotymv1PoeukxYe31K441Ivq0Pkvx1yZZG4O1KCv3Omdbs7uqzUB4xXHlOub4VsTODzDJ5MWHqlRCB1HHcGjlyT2sVGiovLt0Grvqw5+QXBuinoBY0suX0=");
byte[] var9 = zz35.decode(var7);
var8 = zzZg(var8);
var9 = zzZg(var9);
BigInteger var10 = new BigInteger(1, var8);
BigInteger var11 = new BigInteger(1, var9);
RSAPublicKeySpec var12 = new RSAPublicKeySpec(var10, var11);
PublicKey var5 = KeyFactory.getInstance("RSA").generatePublic(var12);
var4.initVerify(var5);
var4.update(var2);
if (!var4.verify(var14)) {
throw new IllegalStateException("The signature is invalid.");
}
}
解决方案:使用 javassist 工具将这个方法体删除即可
package cn.kiion.aspose.crack.word;
import javassist.*;
import java.io.File;
import java.io.IOException;
/**
*
* @author ZCF
*/
public class WordCrack186 {
public static void main(String[] args) throws NotFoundException, CannotCompileException, IOException {
crackMethod("C:\\Users\\zcf\\Desktop\\aspose-words-18.6-jdk16.jar");
}
public static void crackMethod(String jarFile) throws NotFoundException, CannotCompileException, IOException {
// 获取 Jar 包
ClassPool.getDefault().insertClassPath(jarFile);
// 获取 com.aspose.words.zzZLX 类
ClassPool pool = ClassPool.getDefault();
CtClass c2 = ClassPool.getDefault().getCtClass("com.aspose.words.zzZLX");
// 查找并获取 private static void zzZ(Node var0, Node var1) 方法
CtMethod aMethod = c2.getDeclaredMethod("zzZ", new CtClass[]{pool.get("org.w3c.dom.Node"), pool.get("org.w3c.dom.Node")});
// 重置方法体
aMethod.setBody("return;");
c2.writeFile("设置修改代码后将代码存放的路径");
}
}
执行上面的会在设置的路径生成修改的class和它的类路径,反编译去找到修改了的方法代码,可看到方法体已为空
五、将修改了class替换jar包中的
1.把aspose-words-18.6-jdk16.jar后缀改成rar/zip等能解压的格式,解压为aspose-words-18.6-jdk16(文件名随意)
2.把刚刚生成class文件替换到com.aspose.words中
3.删除aspose-words-18.6-jdk16中META-INF中的.RSA和.SF后缀的文件
4.进入aspose-words-18.6-jdk16的根目录,执行命令jar cvfm aspose-words-18.6-jdk16.jar META-INF/MANIFEST.MF com/ asposewobfuscated/ resources/
18.6版本的校验