springboot工程(单个maven工程)利用proguard实现代码混淆

 使用 proguard 混淆代码只能增加阅读和理解的难度, 并不能百分百保证代码安全。常用的应用场景是项目需要部署到客户机器上,一定程度上防止代码泄露。

proguard简介

ProGuard 是一个混淆代码的开源项目,它的主要作用是混淆代码,ProGuard 包括以下 4 个功能:

  • 压缩(Shrink):检测并移除代码中无用的类、字段、方法和特性(Attribute)
  • 优化(Optimize):对字节码进行优化,移除无用的指令文章来源地址
  • 混淆(Obfuscate):使用 a,b,c,d 这样简短而无意义的名称,对类、字段和方法进行重命名
  • 预检(Preveirfy):在 Java 平台上对处理后的代码进行预检,确保加载的 class 文件是可执行的 

实战演练

实战演练版本:

SpringBoot 版本:2.5.8

JDK版本:1.8

ProGuard 版本:7.1.0

proguard官网: https://www.guardsquare.com/proguard

具体操作步骤如下:

第一步:我们新建一个springboot工程demo,并创建controller、service、entity等类,目录结果如图1-1:

图1-1:demo工程目录结构

pom.xml文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.example</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>demo</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>1.8</java.version>
	</properties>
	<dependencies>
	 <!-- SpringBoot的依赖配置-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.5.8</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
			<version>2.5.8</version>
		</dependency>
		
		<!-- SpringBoot Web容器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.5.8</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <version>2.5.8</version>
        </dependency>
        
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<version>2.5.8</version>
		</dependency>
	</dependencies>

	<build>
		<plugins> 
	        <plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<version>2.1.1.RELEASE</version>
				<executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
			</plugin>
		</plugins>
	</build>

</project>

 springboot启动类 DemoApplication代码:

package com.example.demo;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {
	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}

}

 controller、service、entity等包和类可以忽略,自己定义即可。此刻,springboot的工程的基础完成已经搭建完毕。

正常启动:

正常访问:

 通过Java反编译工具 查看源代码结果如下:

 第二步:接下来开始配置proguard了,首先从pom.xml 开始:

 定义 proguard-maven-plugin 插件且插件位于 spring-boot-maven-plugin 插件的前面

<build>
		<plugins>
           <!--  proguard 代码混淆配置  开始-->
			<plugin>
	            <groupId>com.github.wvengen</groupId>
	            <artifactId>proguard-maven-plugin</artifactId>
	            <version>2.6.0</version>
	            <executions>
	                <!-- 以下配置说明执行mvn的package命令时候,会执行proguard-->
	                <execution>
	                    <phase>package</phase>
	                    <goals>
	                        <goal>proguard</goal>
	                    </goals>
	                </execution>
	            </executions>
	            <configuration>
	            	<proguardVersion>7.1.0</proguardVersion>
	                <!-- 输入Jar的名称,输入混淆前的jar。 -->
	                <injar>${project.build.finalName}.jar</injar>
	                <!-- 输出jar名称,输出混淆后的jar -->
	                <outjar>${project.build.finalName}.jar</outjar>
	                <!-- 是否混淆 默认是true -->
	                <obfuscate>true</obfuscate>
	                <!-- 混淆配置文件proguard.cfg -->
	                <proguardInclude>${project.basedir}/proguard.cfg</proguardInclude>
	                <!-- 项目编译所需要的jar -->
	                <libs>
	                    <lib>${java.home}/lib/rt.jar</lib>
	                    <lib>${java.home}/lib/jce.jar</lib>
	                    <lib>${java.home}/lib/jsse.jar</lib>
	                </libs>
	                <!-- 对输入jar进行过滤比如,如下配置就是对META-INFO文件不处理。 -->
	                <inLibsFilter>!META-INF/**,!META-INF/versions/9/**.class</inLibsFilter>
	                <!-- 输出路径配置,但是要注意这个路径必须要包括injar标签填写的jar -->
	                <outputDirectory>${project.basedir}/target</outputDirectory>
	                <!--配置混淆的一些细节选项,可在proguard.cfg中配置-->
	                <options>
	                </options>
	                <!-- 把jar包放到临时目录以便缩短命令行 -->
	                <putLibraryJarsInTempDir>true</putLibraryJarsInTempDir>
	            </configuration>
	            <dependencies>
                    <dependency>
                        <groupId>com.guardsquare</groupId>
                        <artifactId>proguard-base</artifactId>
                        <version>7.1.0</version>
                        <scope>runtime</scope>
                    </dependency>
                    <dependency>
                        <groupId>com.guardsquare</groupId>
                        <artifactId>proguard-core</artifactId>
                        <version>7.1.0</version>
                        <scope>runtime</scope>
                    </dependency>
                </dependencies>
	        </plugin>
            <!--  proguard 代码混淆配置  结束-->
       
	        <plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<version>2.1.1.RELEASE</version>
				<executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
			</plugin>
		</plugins>
	</build>

 第三步:在项目根目录下新建文件proguard.cfg,文件名对应pom.xml的中文件名即可。

#指定Java的版本
-target 1.8
-dontshrink
#是否关闭字节码级别的优化,如果不开启则设置如下配置
-dontoptimize
#混淆时不生成大小写混合的类名,默认是可以大小写混合
-dontusemixedcaseclassnames
# 对于类成员的命名的混淆采取唯一策略
-useuniqueclassmembernames
#混淆类名之后,对使用Class.forName('className')之类的地方进行相应替代
-adaptclassstrings
#对异常、注解信息予以保留
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
#保留参数名,因为控制器,或者Mybatis等接口的参数如果混淆会导致无法接受参数,xml文件找不到参数
-keepparameternames
# 不混淆所有类,保存原始定义的注释-
-keepclassmembers class * {
                        @org.springframework.context.annotation.Bean *;
                        @org.springframework.beans.factory.annotation.Autowired *;
                        @org.springframework.beans.factory.annotation.Value *;
                        @org.springframework.stereotype.Service *;
                        @org.springframework.stereotype.Component *;
                        }

#忽略warn消息
-ignorewarnings
#忽略note消息
-dontnote
#打印配置信息
-printconfiguration
# 不混淆controller入口类
-keep class com.example.demo.DemoApplication { *; }

 第四步:修改启动类DemoApplication。

 由于默认混淆后的类名为 xx.a.b、xx.c.a,直接使用混淆后的类名作为 bean 会引发重名异常,所以需要修改 BeanName 生成策略。

package com.example.demo;

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.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;

@SpringBootApplication
public class DemoApplication {

	public static class CustomGenerator implements BeanNameGenerator {
        public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
            return definition.getBeanClassName();
        }
    }
	
	public static void main(String[] args) {
		//SpringApplication.run(DemoApplication.class, args);
		 new SpringApplicationBuilder(DemoApplication.class)
         .beanNameGenerator(new CustomGenerator())
         .run(args);
	}

}

第五步:验证。重新打包,启动。

打包成功 


通过Java反编译工具 查看源代码结果如下图,包名、类名已经重新命名,代表代码混淆已生效。

 访问正常:

本文只是单个maven工程实现代码混淆,后面我也会更新多个maven工程实现代码混淆的案例。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Spring Boot是一个开发框架,用于简化基于Java的应用程序的开发和部署。它提供了一个自动化配置的方式来简化开发过程,同时也提供了一些常用的功能模块,如安全、数据库连接等。 ProGuard是一个代码混淆工具,用于保护Java代码免受逆向工程代码分析的攻击。它通过对代码进行优化和混淆,使得反编译后的代码难以理解和修改,从而增加了代码的安全性。 Maven是一个项目管理工具,用于构建、发布和管理Java项目的依赖关系。它可以帮助我们方便地管理项目的依赖关系,包括第三方库和插件。同时,它还提供了一些命令和配置,来支持多模块的项目结构。 在使用Spring BootProGuardMaven实现代码混淆时,我们可以按照以下步骤进行操作: 1. 在Maven中创建一个多模块的项目结构。通过使用Maven的父子项目关系,我们可以在一个主项目中管理多个子模块。 2. 在子模块中引入Spring BootProGuard的依赖。在子模块的pom.xml文件中,添加对Spring BootProGuard的相关依赖配置。 3. 配置ProGuard混淆规则。在子模块中创建一个proguard.cfg文件,并添加相关的混淆规则。这些规则可以用于指定哪些类、方法和字段需要进行混淆,以及如何进行混淆。 4. 在Maven的构建过程中,添加对ProGuard的插件配置。通过对Maven的插件进行配置,使得在构建项目时自动应用ProGuard混淆规则。 5. 构建和执行项目。在Maven中使用命令进行项目的构建和执行,观察代码是否已经被混淆。如果一切顺利,你将会得到一个经过混淆代码。 综上所述,通过使用Spring BootProGuardMaven,我们可以实现Java代码混淆保护。这种方式可以增加代码的安全性,防止代码被逆向工程代码分析的攻击。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值