java打包混淆插件proguard

news2024/9/25 11:13:53

java代码混淆工具ProGuard混淆插件:https://blog.csdn.net/yinjl123/article/details/138922335
ProGuard Maven Plugin 使用指南:https://blog.csdn.net/gitblog_00427/article/details/141350545
ProGuard Maven Plugin 踩坑记
ProGuard代码混淆器如何使用:https://blog.csdn.net/m0_54892309/article/details/131653721

以下实验是基于:springboot+aop

零、基础概念

在Spring Boot项目中,使用Maven混淆插件(如proguard-maven-plugin)进行打包是一种提高Java应用安全性、减少代码体积和隐藏实现细节的手段。混淆(Obfuscation)通常涉及重命名类、方法、字段等,移除未使用的代码,以及通过其他方式使反编译和理解原始代码变得更加困难。下面是对混淆插件的作用、优缺点以及可能出现的问题的详细说明。

混淆插件的作用

  1. 增强安全性:通过使代码难以理解,增加逆向工程的难度,保护源代码不被轻易获取或分析。
  2. 减小体积:通过移除未使用的代码和类,以及压缩常量字符串等方式,减小最终打包文件的体积。
  3. 保护知识产权:防止竞争对手通过分析软件来复制或模仿功能。

优缺点

优点
  • 提高安全性:如上所述,混淆增加了逆向工程的难度。
  • 减小包大小:优化后的代码包更小,便于分发和部署。
  • 加速加载时间:更小的包和更紧凑的代码结构可能有助于加快应用的启动和加载时间。
缺点
  • 调试困难:混淆后的代码对于开发者来说几乎不可读,这极大地增加了调试和排错的难度。
  • 性能影响:虽然大多数情况下性能影响很小,但某些情况下混淆可能导致微小的性能下降,特别是当使用了复杂的混淆规则时。
  • 配置复杂:需要仔细配置混淆规则以确保关键代码不被错误地混淆,这可能需要一定的学习和测试。
  • 兼容性问题:混淆可能破坏与反射、序列化等机制相关的兼容性,这些机制依赖于类的确切名称和签名。

可能出现的问题

  1. 反射问题:如果应用使用了Java反射API来访问类、方法或字段,混淆可能会改变这些成员的名称,导致反射失败。
  2. 序列化问题:如果应用涉及对象的序列化(如将对象保存到文件或数据库),混淆可能会破坏类的签名,导致序列化数据无法正确反序列化。
  3. 第三方库兼容:混淆可能破坏与第三方库的兼容性,特别是当这些库依赖于特定的类名或方法签名时。
  4. 调试困难:如前所述,混淆后的代码几乎不可读,使得调试过程变得非常困难。

结论

在决定是否在Spring Boot项目中使用Maven混淆插件时,需要权衡其优缺点以及可能带来的问题。如果你的项目特别关注安全性,并且愿意接受调试和维护方面的挑战,那么混淆可能是一个值得考虑的选择。然而,如果你的项目更注重开发效率和可维护性,或者不需要特别高的安全性保障,那么可能需要重新考虑是否使用混淆。

一、测试项目源码

image.png

二、引入maven proguard插件

<build>
        <plugins>

            <!-- proguard混淆插件-->
            <plugin>
                <groupId>com.github.wvengen</groupId>
                <artifactId>proguard-maven-plugin</artifactId>
                <version>2.6.0</version>
                <executions>
                    <execution>
                        <!-- 打包的时候开始混淆-->
                        <phase>package</phase>
                        <goals>
                            <goal>proguard</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <proguardVersion>7.1.0</proguardVersion>
                    <injar>${project.build.finalName}.jar</injar>
                    <!--输出的jar-->
                    <outjar>${project.build.finalName}-pg.jar</outjar>
                    <!-- 是否混淆-->
                    <obfuscate>true</obfuscate>
                    <options>
                        <option>-target 1.8</option> <!--指定java版本号-->
                        <option>-dontshrink</option> <!--默认开启,不做收缩(删除注释、未被引用代码)-->
                        <option>-dontoptimize</option><!--默认是开启的,这里关闭字节码级别的优化-->
                        <option>-adaptclassstrings</option><!--混淆类名之后,对使用Class.forName('className')之类的地方进行相应替代-->
                        <option>-useuniqueclassmembernames</option><!--# 对于类成员的命名的混淆采取唯一策略-->
                        <option>-keep class org.apache.logging.log4j.util.* { *; }</option>
                        <option>-dontwarn org.apache.logging.log4j.util.**</option>
                        <option>-keepattributes
                            Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
                        </option><!--对异常、注解信息在runtime予以保留,不然影响springboot启动-->
                        <!--不混淆所有interface接口-->
                        <!--                        <option>-keepnames interface **</option>-->
                        <option>-keepclassmembers enum * { *; }</option><!--保留枚举成员及方法-->
                        <option>-keepparameternames</option>
                        <option>-keepclasseswithmembers public class * {
                            public static void main(java.lang.String[]);}
                        </option> <!--保留main方法的类及其方法名-->
                        <!--忽略note消息,如果提示javax.annotation有问题,那麽就加入以下代码-->
                        <option>-dontnote javax.annotation.**</option>
                        <option>-dontnote sun.applet.**</option>
                        <option>-dontnote sun.tools.jar.**</option>
                        <option>-dontnote org.apache.commons.logging.**</option>
                        <option>-dontnote javax.inject.**</option>
                        <option>-dontnote org.aopalliance.intercept.**</option>
                        <option>-dontnote org.aopalliance.aop.**</option>
                        <option>-dontnote org.apache.logging.log4j.**</option>
                        <!--  ##### 以下为需要根据项目情况修改 comment by 郭秀志 20200719 ##### -->
                        <!--入口程序类不能混淆,混淆会导致springboot启动不了-->
                        <option>-keep class com.example.basePro.BaseJavaProjectApplication</option>
                        <option>-keep class com.example.basePro.annotation.** {*;}</option>
                        <option>-keep class com.example.basePro.bean.** {*;}</option>
                        <!--  ##### 以上为需要根据项目情况修改  comment by 郭秀志 20200719 ##### -->
                        <option>-keep class org.springframework.boot.** { *; }</option>
                        <option>-keep interface * extends * { *; }</option>
                        <!--不混淆所有类,保存原始定义的注释-->
                        <option>-keepclassmembers class * {
                            @org.springframework.beans.factory.annotation.Autowired *;
                            @org.springframework.beans.factory.annotation.Value *;
                            }
                        </option>
                    </options>
                    <libs>
                        <!-- 添加依赖 java8-->
                        <lib>${java.home}/lib/rt.jar</lib>
                        <lib>${java.home}/lib/jce.jar</lib>
                        <lib>${java.home}/lib/jsse.jar</lib>
                    </libs>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>com.guardsquare</groupId>
                        <artifactId>proguard-base</artifactId>
                        <version>7.1.0</version>
                    </dependency>
                    <dependency>
                        <groupId>com.guardsquare</groupId>
                        <artifactId>proguard-core</artifactId>
                        <version>7.1.0</version>
                    </dependency>
                </dependencies>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.7.18</version>
                <configuration>
                    <mainClass>com.example.basePro.BaseJavaProjectApplication</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>

三、混淆结果

-pg后缀的是混淆之后的jar解压的文件,类名也被混淆了,同时生成两个文件proguard.map.txt、proguard_seed.txt
image.png
class文件内容记事本打开
image.png
class文件内容IDEA打开
image.png

PS D:\javaPro\java_baseProject\target> java -jar .\demo-0.0.1-SNAPSHOT.jar

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.3.7.RELEASE)

2024-08-27 08:56:58.207  INFO 26124 --- [           main] c.e.basePro.BaseJavaProjectApplication   : Starting BaseJavaProjectApplication on LAPTOP-E5BC3
SCU with PID 26124 (D:\javaPro\java_baseProject\target\demo-0.0.1-SNAPSHOT.jar started by slh in D:\javaPro\java_baseProject\target)
2024-08-27 08:56:58.209  INFO 26124 --- [           main] c.e.basePro.BaseJavaProjectApplication   : No active profile set, falling back to default prof
iles: default
2024-08-27 08:56:59.558  INFO 26124 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2024-08-27 08:56:59.581  INFO 26124 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2024-08-27 08:56:59.582  INFO 26124 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.41]    
2024-08-27 08:56:59.661  INFO 26124 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2024-08-27 08:56:59.661  INFO 26124 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization complete
d in 1383 ms
 _ _   |_  _ _|_. ___ _ |    _ 
| | |\/|_)(_| | |_\  |_)||_|_\ 
     /               |
                        3.4.2
2024-08-27 08:57:00.368  INFO 26124 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecut
or'
2024-08-27 08:57:00.746  INFO 26124 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context
 path ''
2024-08-27 08:57:00.763  INFO 26124 --- [           main] c.e.basePro.BaseJavaProjectApplication   : Started BaseJavaProjectApplication in 2.996 seconds
 (JVM running for 3.398)
2024-08-27 08:57:06.372  INFO 26124 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherSe
rvlet'
2024-08-27 08:57:06.372  INFO 26124 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2024-08-27 08:57:06.382  INFO 26124 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 10 ms
2024-08-27 08:57:06.461  INFO 26124 --- [nio-8080-exec-1] c.e.basePro.annotation.LogRecordAop      : 操作者:diyunlong
2024-08-27 08:57:06.499  INFO 26124 --- [nio-8080-exec-1] c.e.basePro.annotation.LogRecordAop      : 操作日志内容:123
2024-08-27 08:57:06.572  INFO 26124 --- [nio-8080-exec-1] c.e.basePro.annotation.LogRecordAop      : 方法的执行开销是:73

四、在springboot中的使用

https://www.jb51.net/program/316587vdx.htm
看着是成功的:https://www.jianshu.com/p/09b0637525db

Spring Boot项目中实现代码混淆可以通过一些工具实现,比如:ProGuardyGuardJGuard、DexGuard等。最常用的方法是ProGuard,它能够提供优秀的混淆规则以及与构建工具集成的方案,尤其是Maven和Gradle。
ProGuard是一个开源的Java类优化器和混淆器,它可以删除未使用的代码、优化字节码、并对类名、字段、和方法名进行混淆。使用ProGuard不仅增加了逆向工程的难度,还可以使编译后的应用程序更加轻巧。

五、坑与解决

https://docs.pingcode.com/ask/ask-ask/271442.html
https://blog.csdn.net/u014554286/article/details/129037346
https://blog.csdn.net/g5zhu5896/article/details/111320115

  1. 在混淆Spring Boot项目时,要特别注意Spring特有的一些特性,比如依赖注入、AOP、属性配置等,这些功能常常依赖于反射,而混淆可能会破坏这一机制。
<option>-keep class com.example.basePro.annotation.** {*;}</option>
对aop所在的包忽略混淆
  1. beanName冲突解决,修改主启动类中的beanName获取
package com.example.basePro;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;

@SpringBootApplication
public class BaseJavaProjectApplication {

    public static class CustomGenerator implements BeanNameGenerator {

        @Override
        public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
            return definition.getBeanClassName();
        }
    }

    public static void main(String[] args) {
        new SpringApplicationBuilder(BaseJavaProjectApplication.class)
        .beanNameGenerator(new CustomGenerator())
        .run(args);
    }

}
  1. 在实施代码混淆的过程中,可能会遇到一些问题,例如混淆导致的运行时异常、第三方库兼容性问题等。此时,你可能需要调整混淆规则,添加相应的-keep选项来避免这些问题。
  2. 调整插件执行顺序:确保proguard-maven-pluginmaven-compiler-plugin之后但在spring-boot-maven-plugin之前运行。然而,由于spring-boot-maven-plugin通常会处理整个应用程序的打包,包括将类文件和依赖项打包到一个可执行的jar中,因此直接在Spring Boot打包之前进行混淆可能不是最佳选择。
  3. 启动混淆包,无主清单问题,原因是混淆后的目录结构和springboot打包不同,缺少BOOT-INF目录,将混淆后的文件复制到项目jar\BOOT-INF\classes包内。然后再运行原始的jar包可正常运行。

image.png
Snipaste_2024-08-26_14-20-12.png
针对上述问题,将输入数据的jar地址设置相同,给出如下解决方案:

<injar>${project.build.finalName}.jar</injar>
<!-- 输出jar名称,输入输出jar同名的时候就是覆盖,也是比较常用的配置。 -->
<outjar>${project.build.finalName}.jar</outjar>

最后结果:
image.png

  1. swagger与proguard之间的兼容性,未解决

有springfox包解决,未尝试https://www.jb51.net/program/316587vdx.htmhttps://www.jb51.net/program/316587vdx.htm

  1. 多模块之间依赖,未测试
  2. mybatis兼容性**,未测试**

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2093255.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

火爆全网的扩散模型(Diffusion Model)到底是什么?只看这篇就够了!绝对通俗易懂!草履虫看完都要点头!| 附完整代码 + 详细注释

最近在做蛋白从头设计相关研究&#xff0c;看了超多文献&#xff08;后面也想慢慢把它们分享出来嘿嘿嘿&#xff09;&#xff01;发现现在最新的模型其实多数都是基于扩散模型&#xff08;Diffusion Model&#xff09;&#xff0c;既然如此&#xff0c;依据咱们要知道的尿性&am…

【Python进阶】学习Python必须要安装PyCharm。一篇文章带你总结一下安装PyCharm的注意事项,文末附带PyCharm激活码!!!

PyCharm激活码&#xff08;文末附带精品籽料&#xff09;&#xff1a; K384HW36OB-eyJsaWNlbnNlSWQiOiJLMzg0SFczNk9CIiwibGljZW5zZWVOYW1lIjoibWFvIHplZG9uZyIsImxpY2Vuc2VlVHlwZSI6IlBFUlNPTkFMIiwiYXNzaWduZWVOYW1lIjoiIiwiYXNzaWduZWVFbWFpbCI6IiIsImxpY2Vuc2VSZXN0cmljdG…

ComfyUI的优势+安装+基础介绍,干货内容,建议收藏!!!

简介 ComfyUI是一个基于节点流程的稳定扩散操作界面&#xff0c;通过流程实现了更加精准的工作流定制和完善的可复现性。 ComfyUI 与Webui 的区别&#xff1a; 一&#xff0c;界面设计&#xff1a; Web UI提供了直观友好的图形界面&#xff0c;适合初学者和非技术人员使用。…

JSON数据的解析与生成:深入Python的实践与应用

目录 一、JSON基础 1.1 JSON简介 1.2 Python中的JSON处理 二、解析JSON字符串到Python字典 2.1 使用json.loads()函数 2.2 异常处理 三、将Python字典转换为JSON字符串 3.1 使用json.dumps()函数 3.2 格式化输出 3.3 将Python对象写入文件 四、将Python对象写入JSON…

P01-何谓Java方法

P01-何谓Java方法 一、System.out.println()分析 二、剖析方法 谈到方法&#xff0c;我就突然想到了c函数&#xff1a; 其实&#xff1a;Java 方法和 C 函数在许多方面确实有类似之处&#xff0c;但它们也存在一些显著的差异。下面是它们的一些共同点和不同点&#xff1a; 共同…

POS机的接口

联迪的POS机 读取付款方式 private void Form_MisPos_Load(object sender, EventArgs e) { List<Trans> list MisPos.GetTransList(); int col 0; int y 15; int colcount 3; Panel p panel3;…

vben:对话框组件

本文将介绍如何在vben admin vue 框架中&#xff0c;创建对话框组件&#xff0c;并成功应用的代码。代码即插即用。 结果如下图所示&#xff0c; 一、创建对话框组件 创建 myModal/index.vue <template><div><BasicModalregister"registerModal"v-…

探索《黑神话:悟空》背后的编程技术

《黑神话&#xff1a;悟空》作为一款备受期待的动作角色扮演游戏&#xff0c;以其卓越的视觉效果和流畅的游戏体验吸引了全球玩家的关注。这款游戏不仅在艺术设计和技术实现上展现了极高的水准&#xff0c;其背后的编程技术更是保证了游戏顺利运行和出色表现的关键因素。在这篇…

马铃薯叶片病害识别系统+Python+图像识别+人工智能+深度学习+卷积神经算法+计算机课设项目

一、介绍 马铃薯叶片病害识别系统。本项目使用Python作为主要开发语言&#xff0c;基于TensorFlow等深度学习框架搭建ResNet50卷积神经算法网络模型&#xff0c;通过对收集到的3种常见的马铃薯叶片病害数据集&#xff08;‘早疫病’, ‘健康’, ‘晚疫病’&#xff09;进行训练…

计算机毕业设计 基于SpringBoot框架的网上蛋糕销售系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

‌IP地址为什么是8位数:‌深入解析IPv4地址的设计原理与应用

当我们谈论IP地址时&#xff0c;‌通常指的是IPv4地址&#xff0c;‌它由四段8位二进制数构成&#xff0c;‌每段通常转换为十进制数表示&#xff0c;‌范围从0到255。‌这种8位数的设计并非随意&#xff0c;‌而是基于一系列精心的考虑和权衡。‌本文将深入探讨IP地址为什么是…

心觉:颠覆学习,开启无限可能

很多人一天到晚地在学习 买课程&#xff0c;看书&#xff0c;看视频&#xff0c;看直播 网上查资料学习 总之不是在学习&#xff0c;就是在学习的路上 沉浸在学习中无法自拔 乐在其中&#xff0c;但是真正的收获呢&#xff0c;没有&#xff0c;或者说非常少 首先我们来讲…

ORACLE 统计信息的备份与恢复

备份 --需要先创建统计信息基础表 exec dbms_stats.create_stat_table(USER1,STAT_TIMESTAMP); --导出某个用户的所有统计信息 exec dbms_stats.export_schema_stats(USER1,STAT_TIMESTAMP);--测试(插入100条&#xff0c;更新统计信息&#xff0c;略) select num_rows,last_ana…

Python和C++(CUDA)及Arduino雅可比矩阵导图

&#x1f3af;要点 对比三种方式计算读取二维和三维三角形四边形和六面体网格运动学奇异点处理医学图像成像组学分析特征敏感度增强机械臂路径规划和手臂空间操作变换苹果手机物理稳定性中间轴定理 Python雅可比矩阵 多变量向量值函数的雅可比矩阵推广了多变量标量值函数的…

Renesa Version Board开发RT-Thread 之Client(WIFI)和上位机的数据传输

目录 概述 1 系统框架 1.1 模块介绍 1.1 Version-Board 开发板 1.1.1 Vision-Board简介 1.1.2 Vision-Board的资源 1.2 框架介绍 2 上位机App 2.1 UI设计 2.2 代码实现 3 功能测试 3.1 网络连接 3.2 功能测试 概述 本文主要Renesa Version Board开发RT-Thread 之…

MIX滤镜大师 v4.9.6.5 — 内置超过130款滤镜

MIX滤镜大师内置了超过 130 款高品质滤镜&#xff0c;涵盖多种照片风格&#xff0c;包括胶片时代的专业彩色反转片滤镜、自动识别人脸并磨皮增白的自拍滤镜、讲究线条和影调的单色滤镜以及追求夸张色彩的 LOMO 滤镜。此版本已解锁全部功能&#xff0c;去除广告&#xff0c;提供…

量化交易backtrader实践(四)_评价统计篇(4)_多个回测的评价列表

本节目标 在第1节里&#xff0c;我们认识了backtrader内置评价指标&#xff0c;了解了每个指标的大概内容&#xff1b;在第2节里把内置评价指标中比较常用的指标进行了获取和输出&#xff1b;第3节里我们探索其他backtrader中没有的评价指标&#xff0c;并对pyfolio, empyrica…

图形化编程系统学习10

项目需求&#xff1a; 点击绿旗&#xff0c;可以使用键盘控制小兔子在地图上移动&#xff0c;收集食物&#xff0c;但只能在黄色道路上移动。 食物碰到小兔子会变大后隐藏&#xff0c;并发出声音。 收集完所有食物&#xff0c;回到温暖的小窝 。 思路解析 1、添加背景和角色…

【书生大模型实战营】进阶岛 第1关 探索 InternLM 模型能力边界

文章目录 【书生大模型实战营】进阶岛 第1关 探索 InternLM 模型能力边界学习任务Bad Case 1&#xff1a;Bad Case 2&#xff1a;Bad Case 3&#xff1a;Bad Case 4&#xff1a;Bad Case 5&#xff1a;Good Case 1&#xff1a;Good Case 2&#xff1a;Good Case 3&#xff1a;G…