ProGuard加密混淆Java代码

发布时间:2023年12月29日

ProGuard介绍

ProGuard能够通过压缩、优化、混淆、预检等操作,检测并删除未使用的类,字段,方法和属性,分析和优化字节码,使用简短无意义的名称来重命名类,字段和方法。从而使代码更小、更高效、更难进行逆向工程。

maven插件方式混淆

<!-- ProGuard混淆插件-->
            <plugin>
                <groupId>com.github.wvengen</groupId>
                <artifactId>proguard-maven-plugin</artifactId>
                <version>2.6.0</version>
                <executions>
                    <!--   package时执行proguard   -->
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>proguard</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <!--  输入的jar包  -->
                    <injar>${project.build.finalName}.jar</injar>
                    <!--  输出的jar包  -->
                    <outjar>${project.build.finalName}.jar</outjar>
                    <!--  是否进行混淆,默认为true  -->
                    <obfuscate>true</obfuscate>
                    <!--  配置文件,通常为proguard.cfg,主要对options选项进行配置,所有的options选项都可以进行配置  -->
                    <proguardInclude>${project.basedir}/proguard.cfg</proguardInclude>
                    <!--  额外的jar,项目编译所需的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/**</inLibsFilter>
                    <!--  输出路径配置,必须包含injar标签中填写的jar  -->
                    <outputDirectory>${project.build.directory}</outputDirectory>
                    <!-- 因为window的cmd有长度限制,而proguard混淆时依赖太多的jar包导致命令行过长在proguard-maven-plugin的configuration中加入下面配置,这个配置会把jar包放到临时目录以便缩短命令行-->
                    <putLibraryJarsInTempDir>true</putLibraryJarsInTempDir>
                </configuration>
            </plugin>

proguard.cfg配置文件

文件位置和pom.xml文件同级别

# 指定 java 版本
-target 1.8
-keepdirectories
# 关闭对代码进行优化压缩,开启会删除从未使用的类或者类成员变量等
-dontshrink
# 列出未使用的代码,可打印到标准输出或写入指定文件
#-printusage
# 关闭字节码级别的优化,如果不开启则设置如下配置,默认开启。
-dontoptimize
# 关闭预检,预检主要针对JavaME,Java6以后都不用预检,不关闭启动会报错: Expected stackmap frame at this location.
-dontpreverify
# 不生成大小写混写的类名
-dontusemixedcaseclassnames
# 对类成员的命名混淆采取唯一策略
-useuniqueclassmembernames
# 混淆类名之后,对使用Class.forName('className')之类的地方进行相应替代
-adaptclassstrings
#对异常、注解信息予以保留
#MethodParameters: #所有类(包括接口)的方法参数不混淆(包括没被keep的) 如果参数混淆了 mybatis mapper 参数绑定会出错(如#{id}
-keepattributes MethodParameters,Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
# 此选项将保存接口中的所有原始名称(不混淆)-->
-keepnames interface ** { *; }
#保留参数名,因为控制器,或者Mybatis等接口的参数如果混淆会导致无法接受参数,xml文件找不到参数
-keepparameternames
# 保留枚举成员及方法
-keepclassmembers enum * { *; }
#忽略warn消息
-ignorewarnings
#忽略note消息
-dontnote
#打印配置信息
-printconfiguration
# 排除混淆 指定的类名且类中的方法也不混淆
-keep class com.test.ac.processing.Application{<methods>;}
#配置不混淆
-keep class com.test.ac.config.** {*;}
#实体不混淆
-keep class com.test.ac.entity.** {*;}
#配置包路径不混淆
-keeppackagenames com.test.ac.config
#注解了Aspect的都不混淆,由于把framework下的所有类都不混淆,所以此配置就可有可无了
-keep @org.aspectj.lang.annotation.Aspect class * {*;}



配置完之后执行package命令就会有混淆之后的jar包了.

常用属性

-keep

-keep [,modifier,...] class_specification; 指定该类以及类的成员和方法为entry points,不被ProGuard混淆

-keepclassmembers

-keepclassmembers [,modifier,...] class_specification: 指定类的某些成员不被混淆,注意类名还是会被混淆

-keepnames

-keepnames class_specification: -keepclassmembers,allowshrinking class_specification的别名,保留名称不被混淆,但可以被压缩

-keepclassmembernames

-keepclassmembernames class_specification; -keepclasseswithmembers,allowshrinking class_specification的别名,保留名称不被混淆,但可以被压缩

-keeppackagenames

-keeppackagenames [package_filter]: 保持包路径名称不混淆

混淆后代码

class文件的一些变量名称也会发生变化,让代码可读性更差.

可能出现的问题

混淆后自己全部代码没有被放入混淆后的jar包里(jar\BOOT-INF\classes)

原因: proguard-maven-plugin插件放到了spring-boot-maven-plugin插件后面

解决:把proguard-maven-plugin插件放到spring-boot-maven-plugin前面

启动项目提示bean名称重复

因为混淆之后类的命名就会发生重复了,导致bean名称也会重复,导致启动报错,在启动类做以下改动,重新bean名称.

public static void main(String[] args) {
		new SpringApplicationBuilder(Application.class)
				.beanNameGenerator(new AnnotationBeanNameGenerator() {
					@Override
					protected String buildDefaultBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
						return definition.getBeanClassName();
					}
				}).run(args);
	}

CreateProcess error=206, 文件名或扩展名太长。

因为window的cmd有长度限制,而proguard混淆时依赖太多的jar包导致命令行过长;

在proguard-maven-plugin的configuration中加入下面配置,这个配置会把jar包放到临时目录以便缩短命令行 <putLibraryJarsInTempDir>true</putLibraryJarsInTempDir>

如果想让代码更安全,也可以先混淆再使用classFinal加密:?classFinal使用

文章来源:https://blog.csdn.net/zc_huiyanruju/article/details/135220711
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。