ProGuard加密混淆Java代码

ProGuard介绍

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

maven插件方式混淆


            
                com.github.wvengen
                proguard-maven-plugin
                2.6.0
                
                    
                    
                        package
                        
                            proguard
                        
                    
                
                
                    
                    ${project.build.finalName}.jar
                    
                    ${project.build.finalName}.jar
                    
                    true
                    
                    ${project.basedir}/proguard.cfg
                    
                    
                        ${java.home}/lib/rt.jar
                        
                        ${java.home}/lib/jsse.jar
                    
                    
                    !META-INF/**,!META-INF/versions/**
                    
                    ${project.build.directory}
                    
                    true
                
            

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{;}
#配置不混淆
-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]: 保持包路径名称不混淆

混淆后代码

ProGuard加密混淆Java代码_第1张图片

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包放到临时目录以便缩短命令行 true

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

你可能感兴趣的:(java,安全)