正确使用 Aspose.Diagram for Java

最近在鼓捣java 如何生成visio图表,苦于没有API,找到了aspose这个神器,下载试用版本之后,发现最多只能生成10个元素,而且有水印。下面尝试如何去掉水印与元素限制。

本文章所涉及的软件均可从网上获取,但是只能用于学习之用,不能用于商业目的,正版的话请前往 aspose下载。

首先本次需要用到的软件:

JByteMod-Beta-1.8.2.zip

aspose-diagram-20.1-jdk16.jar

jboss-javassist-javassist.zip

第一步:使用JByteMod打开aspose-diagram-20.1-jdk16.jar,找到反编译之后找到License类,找到关键的设置License方法,如下:

 public void setLicense(final InputStream inputStream) throws Exception {
        Document parse = null;
        if (inputStream != null) {
            try {
                parse = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream);
            }
            catch (Exception ex) {
                throw new DiagramException("Error when parse license stream.");
            }
        }
        this.a(parse);
    }

可以看到这是从某个配置文件里面输入一些关键的鉴权信息,那么配置文件里面应该有些什么东西呢,接着看:

 void a(final Element element) throws Exception {
        try {
            int n = 0;
            final Node item = element.getElementsByTagName("Data").item(0);
            final Node item2 = element.getElementsByTagName("Signature").item(0);
            if (item != null && item2 != null) {
                final Node a = afl.a(item.getChildNodes(), "Products");
                final NodeList list = (a != null) ? a.getChildNodes() : null;
                if (list != null) {
                    this.b = new String[list.getLength()];
                    for (int i = 0; i < list.getLength(); ++i) {
                        this.b[i] = a(a(list.item(i).getLastChild()));
                        if (this.b[i].startsWith("Conholdate.")) {
                            n = 1;
                        }
                    }
                }
                a(item, item2, n);
                final Node a2 = afl.a(item.getChildNodes(), "EditionType");
                if (a2 != null) {
                    this.c = e(a(a2.getLastChild()));
                }
                final Node a3 = afl.a(item.getChildNodes(), "SerialNumber");
                if (a3 != null) {
                    this.d = a(a3.getLastChild());
                }
                else {
                    this.d = "";
                }
                final Node a4 = afl.a(item.getChildNodes(), "SubscriptionExpiry");
                if (a4 != null) {
                    this.e = b(a4.getLastChild());
                }
                final Node a5 = afl.a(item.getChildNodes(), "LicenseExpiry");
                if (a5 != null) {
                    this.f = b(a5.getLastChild());
                }
                final Node a6 = afl.a(item.getChildNodes(), "OemPublicKeyToken");
                if (this.g != null) {
                    this.g = a(a6.getLastChild());
                }
                else {
                    this.g = "";
                }
            }
        }
        catch (DiagramException ex) {
            throw ex;
        }
        catch (Exception ex2) {
            throw new DiagramException("The license is invalid. ");
        }
    }

 

 通过上面的节点解析代码看的不是很全,再继续看:

    private static void a(final Node node, final Node node2, final int n) throws Exception {
        final String s = (node != null) ? afl.a(node) : "";
        String replaceAll;
        if (s.equals("<Data />")) {
            replaceAll = "<Data></Data>";
        }
        else {
            replaceAll = s.replaceAll("&", "&amp;");
        }
        try {
            final KeyFactory instance = KeyFactory.getInstance("RSA");
            String i = License.i;
            if (n == 1) {
                i = "qKFqqhFovZvEYCHeD3N8Oy+AuxrOA8cVvIl4u4qIBMQlzejGyXkiTUjoryuzlhlS2bG80FGmFsH+wUKbYiEkW/4zseZCV/Ej/usbu6yHACQKO/SCy3pYw68Pcv901pvywUnoaYCI2ccCG29+XM+FwpFQuiPb2H7YbI/++SQs6Hk=";
            }
            final PublicKey generatePublic = instance.generatePublic(new RSAPublicKeySpec(new BigInteger(1, bf.a(i, "UTF-8")), new BigInteger(1, bf.a("AQAB", "UTF-8"))));
            final byte[] bytes = replaceAll.getBytes("UTF-16LE");
            final byte[] a = bf.a((node2 != null) ? node2.getLastChild().getNodeValue() : "", "UTF-8");
            final Signature instance2 = Signature.getInstance("SHA1withRSA");
            instance2.initVerify(generatePublic);
            instance2.update(bytes);
            if (!instance2.verify(a)) {
                final PublicKey generatePublic2 = instance.generatePublic(new RSAPublicKeySpec(new BigInteger(1, bf.a("3ki45T6C4lt12J5MbKfrADBCZcE8OTefdngc9IDKg+lzCGYLuxJFDt16awhJFnA23sX+kQ4/eZQ5pNAYjc+ZJ0+pWwvQR4h8GJ3eWvecdFs7KSWwNmFXZCSN+sbrxwEjzzns1kIHuLNf5r+Zaggns+8rqXR19RSJBOcuFqVipIHv56lF53Hc+hx+y9URIaadO1W8dkTqgwExyfjnbDOaCBEH0CqUL1YIICS/wIUTEKhM0ZlwEcIcHl8XTHLVx96DMX4bbVajj78L4KzevQc442DX28KGDJTveEB1pSKWsr0d4FTx7wKS36RBnWv5lwsRErtTZb5ciVIG1iIJrp87VQ==", "UTF-8")), new BigInteger(1, bf.a("AQAB", "UTF-8"))));
                final Signature instance3 = Signature.getInstance("SHA256withRSA");
                instance3.initVerify(generatePublic2);
                instance3.update(bytes);
                if (!instance3.verify(a)) {
                    throw new DiagramException("The signature is invalid.");
                }
            }
        }
        catch (Exception ex) {
            throw new DiagramException("License signature reading error or signature is invalid.");
        }
    }

结合两段代码,重点在于<Data>结构体,配置文件的大致格式,解析的配置文件如下,这里我们新建一个license.xml,复制以下内容。

<License>
    <Data>
        <Products>
            <Product>Aspose.Diagram for Java</Product>
        </Products>
        <EditionType>Enterprise</EditionType>
        <SubscriptionExpiry>20991231</SubscriptionExpiry>
        <LicenseExpiry>20991231</LicenseExpiry>
        <SerialNumber>---</SerialNumber>
    </Data>
    <Signature>---</Signature>
</License>

同时,查看解析的代码,它是采用的RSA加密验证license合法性,我们修改字节码,把这个方法屏蔽掉应该就可以。这里需要使用到javassist 了。新建java工程,新建类,代码如下:

 public static void changeMethod() throws Exception {
        ClassPool.getDefault().insertClassPath(
                "E:/aspose-crack/aspose-diagram-20.1-jdk16.jar");
        CtClass ctclass = ClassPool.getDefault()
                .getCtClass("com.aspose.diagram.License");
        CtMethod[] ms = ctclass.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 == 3
                    && ps[0].getName().equals("org.w3c.dom.Node")
                    && ps[1].getName().equals("org.w3c.dom.Node")) {
                System.out.println("find it!");
                c.insertBefore("{return;}");
            }

        }
        ctclass.writeFile("E:/aspose-crack/");
    }

其中,具体的jar包输入路径与最终的class文件输出路径可以自定义。

然后使用压缩文件打开 aspose-diagram-20.1-jdk16.jar,替换生成的License.class文件,然后把META-INF下的签名文件全部删掉。参考下面代码就能愉快使用了。

public static boolean getLicense() throws Exception {
        boolean result = false;
        try {
            InputStream is = new FileInputStream(new File("License.xml文件路径"));
            License license= new License();
            license.setLicense(is);
            result = true;
            is.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
        return result;
    }

在准备绘制visio之前,调用一次getLicense()方法就可以去掉水印与元素个数的限制了。

再次强调,仅供学习使用。

github参考资料(github是个好网站):

https://github.com/aspose-diagram/Aspose.Diagram-for-Java

https://github.com/asposemarketplace/Aspose-Diagram-Java

posted @ 2020-02-27 11:38  yueenmore  阅读(1026)  评论(0编辑  收藏  举报