Java打包混淆之Allatori

本文介绍了使用Allatori对Java代码进行混淆以增强安全性,特别是与Spring Boot项目结合的过程。Allatori不仅能混淆代码,还提供附加功能,如最小化应用大小和提升运行速度。混淆过程中常见的问题包括保持类名唯一、处理反射、不混淆Mapper接口等。混淆虽然能提高反编译难度,但并非完全安全,仍需结合其他保护措施。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.前言

熟悉Java的人都知道Java代码编译成class文件就可以部署运行了,但是class文件通过jdk-gui等工具是很容易反编译就看到源代码的,在代码给到客户私有化部署时,为了保护咱们自己的知识产权,我们会使用加密、花指令、混淆等方式对代码进行保护,其中加密方式时最安全的,但是实现需要比较强的能力,花指令其实就是防止反编译,而混淆就是提升代码反编译之后的阅读障碍。混淆是简单而且易于操作的,所以基础的保护就采用这中方式,但是混淆也是有对应反混淆的工具的,所以如果是超级严格的知识产权保护,一般都是采用混淆配合另外两种方式一起使用的,我这里是采用第三方混淆工具Allatori对我们的代码进行混淆的,还有另外一个常用的纯java开发的混淆工具是ProGuard。

2.Allatori

Allatori是第二代Java混淆器,Allatori不仅能混淆代码还提供了很多附加功能,使得被Allatori混淆的代码几乎不可能被逆向解析,同时Allatori还可以最小化应用程序的大小,提升代码运行速度,Allatori和其他混淆器一样具有水印和过期功能。

2.1Allatori配置文件的结构以及各个标签的作用

<config>
    <!-- input标签是用来设置将要被混淆的jar(war,ear)文件的,input标签至少必须包含一个jar或dir标签来配置输入输出文件  -->
    <!-- input标签的basedir属性,可选配置,用来设置jar文件的相对文件目录的 -->
    <!-- input标签的single-jar属性,可选配置,Allatori会创建一个包含所有混淆过的类的额外输出jar文件-->
    <input basedir="input-jars" single-jar="application.jar">
        <!-- jar标签,设置输入输出文件,这种是具体的jar文件,输入输出同名的话,混淆后的文件会覆盖混淆前的为文件  -->
        <jar in="app.jar" out="app-obf.jar"/>
        <!-- jar标签,通配符的配置方式  -->
        <jar in="input/*.jar" out="output/*.jar"/>
        <!-- dir标签,配置输入输出目录  -->
        <dir in="in-dir" out="out-dir"/>
    </input>
    
    <!-- classpath标签用于设置被混淆程序的类路径,它不必配置应用程序所需的所有jar包,但是缺少依赖包可能混淆没那么彻底,同时混淆的过程中也可能会出现告警 -->
    <!-- basedir,与input的basedir同理,配置一个相对路径 -->
    <classpath basedir="library-jars">
        <!-- 添加一个library.jar的jar到类路径中 -->
        <jar name="library.jar"/>
        <!-- 配置一个目录下的jar到类路径 -->
        <jar name="lib/*.jar"/>
        <!-- 配置lib2下的目录以及它的子目录下的jar到类路径 -->
        <jar name="lib2/**/*.jar"/>
    </classpath>

    <!-- keep-names标签用于在混淆过程中标记不需要重命名的类、方法、字段的名称,所以该标签下有class/method/field这三种标签。通常不建议混淆的几种情况如下:  -->
    <!-- 1.如果混淆的jar是一个公共类库,那么public类型的api就不能被混淆(即不需要重命名) -->
    <!-- 2.如果混淆的jar是一个独立的应用程序,那么该应用程序的启动类即主类不应该被混淆 -->
    <!-- 3.如果某些类和方法被反射使用了,那么这些类和方法也不应该被混淆 -->
    <keep-names>
        <!-- class标签用来匹配类,它有access、template、ignore、stop四个属性,至少要带有access、template中的一个属性 -->
        <!-- access通过访问权限隔离来匹配,带加号('+'),表示更宽的权限范围都可以匹配上 -->
        <!-- template通过表达式来匹配,*标识通配符 -->
        <!-- ignore可选,当它设置为'true'或'yes'时,类会被混淆,但是方法和属性不会被混淆 -->
        <!-- stop可选,当它设置为'true'或'yes'时,类、方法、属性都会被混淆 -->
        
        <!-- stop属性,控制是否被重命名,等于true,配置的class com.company.abc.*下的类、方法、属性都会被重命名 -->
        <class template="class com.company.abc.*" stop="true"/>
        
        <!-- 下面是不需要重名名的规则 -->
        <!-- 匹配任何包下名字为'Main'的类 -->
        <class template="class *.Main"/>

        <!-- 匹配以‘Bean’结尾的类 -->
        <class template="class *Bean">
            <!-- 匹配所有的属性,access匹配方式 -->
            <field access="private+"/>
            <!-- 匹配所有public int的属性 -->
            <field template="public int *"/>
            <!-- 匹配所有的静态属性 -->
            <field template="static *"/>
            <!-- 匹配所有protected和public且为String的属性 -->
            <field template="protected+ java.lang.String *"/>
            <!-- 匹配所有方法 -->
            <method template="private+ *(**)"/>
            <!-- 匹配所有Get方法 -->
            <method template="private+ get*(**)"/>
            <!-- 匹配所有参数为String的方法,同时parameters="keep"会使方法的参数不会被混淆 -->
            <method template="private+ *(java.lang.String)" parameters="keep"/>
        </class>

        <!-- 匹配序列化的类 -->
        <class template="class * instanceof java.io.Serializable">
            <field template="static final long serialVersionUID"/>
            <method template="void writeObject(java.io.ObjectOutputStream)"/>
            <method template="void readObject(java.io.ObjectInputStream)"/>
            <method template="java.lang.Object writeReplace()"/>
            
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值