您的位置 首页 java

基于Maven的SpringBoot工程中,如何进行Java代码混淆?

前言

代码混淆,是将 计算机程序 的代码转换成一种功能上等价,但是难于阅读和理解的形式的行为。 代码混淆 可以用于程序源代码,也可以用于程序编译而成的中间代码。执行代码混淆的程序被称作代码混淆器。

为什么要做代码混淆?

代码混淆的主要目的是为了保护源代码,阻止 反向工程 。反向工程会带来许多问题,诸如知识产权泄露,程序弱点暴露易受攻击等。使用即时编译技术的语言,如 Java 、C#所编写的程序更容易受到反向工程的威胁。 但是代码混淆并不能真正阻止反向工程,只能增大其难度。因此,对于对安全性要求很高的场合,仅仅使用代码混淆并不能保证 源代码 的安全。 还可以通过代码虚拟化,代码加密,压缩等多种方式来提高代码的安全性。

代码混淆有哪些方式?

  • 将代码中的各种元素,如变量,函数,类的名字改写成无意义的名字。比如改写成单个字母,或是简短的无意义字母组合,甚至改写成“__”这样的符号,使得阅读的人无法根据名字猜测其用途。
  • 重写代码中的部分逻辑,将其变成功能上等价但是更难理解的形式。比如将for循环改写成while循环,将循环改写成递归,精简中间变量,等等。
  • 打乱代码的格式。比如删除空格,将多行代码挤到一行中,或者将一行代码断成多行等等。

如何对 JAVA 代码进行混淆?

  1. 在生成 class文件 的过程中(即编译过程),通过修改编译器的代码生成过程,对编译器生成的中间代码进行混淆,最后生成class文件。典型的是jocky,但目前最新的jocky为1.0.3版本,不支持 jdk 1.6。
  2. 在生成class文件后,对class文件进行混淆。典型的是 proguard 、retroguard。但由于并不是所有的class文件都需要混淆,所以将面临复杂的配置工作(配置哪些类需要混淆,哪些类需要混淆),并且程序一旦修改,配置工作又要重新进行。

如何使用proguard进行代码混淆?

主要使用proguard- Maven -plugin插件对 Spring boot代码进行混淆。插件配置如下:

 <build>
    <plugins>
        <!-- ProGuard混淆插件-->
        <plugin>
            <groupId>com.github.wvengen</groupId>
            <artifactId>proguard-maven-plugin</artifactId>
            <version>2.3.1</version>
            <executions>
                <execution>
                    <!-- 混淆时刻,这里是打包的时候混淆-->
                    <phase>package</phase>
                    <goals>
                        <!-- 使用插件的混淆功能 -->
                        <goal>proguard</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <proguardVersion>6.2.2</proguardVersion>
                <!-- 对classes进行加载 -->
                <injar>classes</injar>
                <outjar>${project.build.finalName}.jar</outjar>
                <!-- 输出目录-->
                <outputDirectory>${project.build.directory}</outputDirectory>
                <libs>
                    <lib>${java.home}/lib/rt.jar</lib>
                    <lib>${java.home}/lib/jce.jar</lib>
                </libs>
                <!--混淆-->
                <obfuscate>true</obfuscate>
                <!--是否将生成的PG文件安装部署-->
                <!--<attach>true</attach>-->
                <!--指定生成文件分类-->
                <!--<attachArtifactClassifier>pg</attachArtifactClassifier>-->
                <!--保留pom文件等-->
                <add maven Descriptor>false</addMavenDescriptor>
                <!--外部配置文件-->
                <proguardInclude>../proguard.cfg</proguardInclude>
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>net.sf.proguard</groupId>
                    <artifactId>proguard-base</artifactId>
                    <version>6.2.2</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>
  

其中外部配置文件proguard.cfg内容如下:

 # -keep {Modifier} {class_specification} 防止类和成员被移除或者被重命名
# -keepclassmembers {modifier} {class_specification} 防止成员被移除或者被重命名
# -keepclasseswithmembers {class_specification} 防止拥有该成员的类和成员被移除或者被重命名
# -keepnames {class_specification} 防止成员被重命名
# -keepclasseswithmembernames {class_specification} 防止拥有该成员的类和成员被重命名
# -keepclasseswithmembers
# -basedirectory directoryname  在配置文件中出现的 相对路径 均是相对于该路径
 
 
# 忽略所有警告,否则有警告的时候混淆会停止
-ignorewarnings
# JDK目标版本1.8
-target 1.8
# 不做收缩(删除注释、未被引用代码)
-dontshrink
# 不做优化(变更代码实现逻辑)
-dontoptimize
# 不路过非公用类文件及成员
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
# 优化时允许访问并修改有修饰符的类和类的成员
-allowaccessmodification
# 确定统一的混淆类的成员名称来增加混淆
-useuniqueclassmembernames
# 不混淆所有包名,本人测试混淆后WEB项目问题实在太多,毕竟Spring配置中有大量固定写法的包名
-keeppackagenames
# 不混淆局部变量名
-keepparameternames
# 不混淆所有特殊的类 LocalVariable*Table,
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,Source File ,LineNumberTable,* Annotation *,Synthetic,EnclosingMethod
# 不混淆包下的所有类名
-keep class weg.base.** { <methods>; }
-keep class weg.service.** { <methods>; }
-keep class weg.dao.** { <methods>; }
-keep class weg.util.** { <methods>; }
# 不混淆quartz包下的所有类名,且类中的方法也不混淆
-keep class weg.quartz.** { <methods>; }
# 不混淆model包中的所有类以及类的属性及方法,实体包,混淆了会导致 ORM 框架及前端无法识别
-keep class weg.model.** {*;}
# 不混淆所有的set/get方法,毕竟项目中使用的部分第三方框架(例如 Shiro )会用到大量的set/get映射
-keepclassmembers public class * { void  set*(***);*** get*();}
# 保持类protected不被混淆
-keep public class * { public protected <fields>;public protected <methods>; }
  

配置完成后执行maven命令:

 clean package -DskipTests
  

执行上述代码后,在target目录下会生成3个文件:

  • classes.jar 混淆后的classes文件,里面包含完整的项目结构
  • proguard_map.txt 混淆内容的映射
  • proguard_seed.txt 参与混淆的类

踩坑指南

(1) 报错如下:

 Error: You have to specify '-keep' options if you want to write out kept elements with '-printseeds'.
  

解决方式:根据需求 配置 -keep 要保留的元素

(2)../proguard.cfg配置文件未生效

解决方式:是因为路径写的有问题,此路径是相对于 编译后的 target 文件的路径,如果是maven多模块,这些配置又写在父模块的目录下,重点来了,想要混淆子模块的代码,那么这个路径就是相对于子模块的target文件夹的路径

(3)打包之后不知道混淆成功了没,或者混淆配置生效了没,查看这个 jar 包里的代码又很麻烦

解决方式:outjar配置一个目录即可。如果要上传私服,打包之后却有两个包,混淆的那个包无法直接上传私服,那么outjar配置的jar包名称和${project.build.finalName}一致,即可覆盖。然后一键轻松上传私服。

 <!--class 混淆后输出的jar包 或 文件夹-->
<outjar>${project.build.finalName}.jar</outjar>
  

文章来源:智云一二三科技

文章标题:基于Maven的SpringBoot工程中,如何进行Java代码混淆?

文章地址:https://www.zhihuclub.com/180429.shtml

关于作者: 智云科技

热门文章

评论已关闭

11条评论

  1. You have made your point quite effectively..
    personal essays for college how to write a citation in an essay

  2. Thank you for the auspicious writeup. It in fact was a amusement account it.
    Look advanced to far added agreeable from you! By the way, how can we communicate?

  3. Whoa all kinds of fantastic information!
    write essay for me uk what do i write my college essay on

  4. Reliable posts. Regards!
    what should i write my personal essay about website to write essays for you

  5. Superb forum posts. Cheers!
    writing a hook for an essay essay writing service craigslist

网站地图