java混淆框架proguard结合springboot项目混淆打包

文章介绍了如何使用Proguard混淆Java项目,以增强代码安全性,防止反编译。混淆主要针对关键部分,避免枚举类型混淆导致反序列化失败。配置文件示例展示了如何保留Spring相关注解和特定类不被混淆。最后,文章通过一个SpringBoot示例项目演示了混淆过程和效果,证明混淆后的代码仍能正常运行。
摘要由CSDN通过智能技术生成

    java项目一般是打包成jar运行或者作为依赖给第三方使用的,有的时候,可能不想被别人反编译,于是就对关键部分进行混淆,让代码变得普通人看不懂的地步,很多关键字和变量都是用单个字母表示,达到一种类似加密的效果。

    java中混淆框架proguard,准确来说是一个插件,不需要对他进行编码,只需要进行配置即可。代码混淆,并不是把所有代码进行混淆,这样反而会出错,比如枚举类型如果也进行混淆,那么在使用反射创建实例,并给实例赋值的时候,枚举类型会反序列化失败。

    proguard提供了可以对哪些包,类,方法等不进行混淆的配置,我们可以将枚举配置在这里。

    因为springboot提供了打包插件spring-boot-maven-plugin,所以我们的混淆需要在springboot打包的插件之前,就是我们要对混淆之后的代码通过spring-boot-maven-plugin进行打包。

    下面是一个配置示例proguard.cfg:

# 指定不警告尚未解决的引用和其他问题
-dontwarn
# JDK目标版本1.8
-target 1.8
# 不做收缩(删除注释、未被引用代码)
-dontshrink
# 不做优化(变更代码实现逻辑)
-dontoptimize
# 混淆时不使用大小写混合,混淆后的类名为小写
-dontusemixedcaseclassnames
# 不去忽略非公共的库类
-dontskipnonpubliclibraryclasses
# 指定不跳过包可见的库类成员(字段和方法)。
# 默认情况下,proguard在解析库类时会跳过包可见的库类成员。当我们确实引用了包可见的类成员时,需要设置此项
-dontskipnonpubliclibraryclassmembers
# 确定统一的混淆类的成员名称来增加混淆
-useuniqueclassmembernames
# 优化时允许访问并修改有修饰符的类和类的成员
-allowaccessmodification
# 不混淆所有包名
#-keeppackagenames
# 需要保持的属性:异常,注解等
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod
# spring 相关的注解,不要混淆
-keepclassmembers class * {
     @org.springframework.** *;
     @javax.annotation.PostConstruct *;
     @javax.annotation.PreDestroy *;
}
# spring 相关的注解,不要混淆
-keepclassmembers class * {
     @org.springframework.beans.factory.annotation.Autowired <fields>;
     @org.springframework.beans.factory.annotation.Autowired <methods>;
}

#混淆时是否记录日志
#-verbose

# 不混淆所有的set/get方法
-keepclassmembers public class * {void set*(***);*** get*();}
# 不混淆本工程中的部分特殊类
-keep class com.xxx.hello.Hello {*;}
-keep class com.xxx.hello.domain.BookStatus {*;}

# 不混淆所有包含Component等注解的类
-keep @org.springframework.stereotype.Component class * {*;}
-keep @org.springframework.stereotype.Service class * {*;}
-keep @org.springframework.web.bind.annotation.RestController class * {*;}
-keep @org.springframework.context.annotation.Configuration class * {*;}

    pom.xml

 <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.8</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.20</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>com.github.wvengen</groupId>
                <artifactId>proguard-maven-plugin</artifactId>
                <version>2.0.14</version>
                <executions>
                    <execution>
                        <!--混淆时刻,这里是打包的时候混淆-->
                        <phase>package</phase>
                        <!--使用插件的混淆功能-->
                        <goals>
                            <goal>proguard</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <proguardVersion>6.1.0</proguardVersion>
                    <!--是否混淆-->
                    <obfuscate>true</obfuscate>
                    <!-- 加载配置文件 -->
                    <proguardInclude>proguard.cfg</proguardInclude>
                    <!-- 对什么东西进行加载-->
                    <injar>${project.build.finalName}.jar</injar>
                    <!--class 混淆后输出的jar包 或 文件夹-->
                    <outjar>${project.build.finalName}.jar</outjar>
                    <!-- 输出目录-->
                    <outputDirectory>${project.build.directory}</outputDirectory>
                    <libs>
                        <!-- Include main JAVA library required.-->
                        <lib>${java.home}/lib/rt.jar</lib>
                        <!-- Include crypto JAVA library if necessary.-->
                        <lib>${java.home}/lib/jce.jar</lib>
                    </libs>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>net.sf.proguard</groupId>
                        <artifactId>proguard-base</artifactId>
                        <version>6.1.0</version>
                    </dependency>
                </dependencies>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>com.xxx.hello.Hello</mainClass>
                    <classifier>exec</classifier>
                    <layout>ZIP</layout>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    java项目在最后给出来,大致意思是,启动springboot web项目,提供两个接口add,get,一个是用来添加一个book对象,一个用来读取这个book对象。

    打包之后的文件:

    可以看到hello-1.0-SNAPSHOT_proguard_base.jar要早于另外两个jar,因为它要先混淆。

    我们可以通过反编译软件jd-gui查看打包后的jar文件:

    这里面对spring相关的都进行过过滤,所以剩下的都是和spring无关的类, 除了BookStatus这个枚举类型之外,都进行了混淆,类名称都直接缩写成了小写字母a,b,c....

    测试写入:

    测试读取:

    都是没问题的,如果我们把BookStatus枚举也进行混淆,那么进行写入的时候,报错:

     意思是反序列化失败, 因为没有BookStatus的枚举常量。

     代码地址:https://gitee.com/buejee/javaproguardexample

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luffy5459

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值