Proguard混淆与Maven集成

时间:2022-06-01 17:17:29

Proguard混淆与Maven集成

1      prouard与maven集成     

2      Proguard配置     

2.1压缩     

2.2.优化     

2.3 混淆     

3.工程搭建     

3.1.Jar工程混淆     

3.2.WEB工程混淆     

 

 

 

 

 

 

 

 

 

 

 

1   prouard与maven集成

 项目工程为Maven项目,在pom.xml配置文件中<plugins></plugins>中添加如下配置:

<plugin>

                <groupId>com.pyx4me</groupId>

                <artifactId>proguard-maven-plugin</artifactId>

                <executions>

                    <execution>

                        <phase>package</phase>

                        <goals>

                            <goal>proguard</goal>

                        </goals>

                    </execution>

                </executions>

                <configuration>

                    <includeDependency>true</includeDependency>

                <proguardVersion>4.8</proguardVersion>

                <obfuscate>true</obfuscate>

                   <maxMemory>1024m</maxMemory>

                <proguardInclude>${basedir}/proguard.conf</proguardInclude>

                    <libs>

                        <lib>${java.home}/lib/rt.jar</lib>

                        <lib>${java.home}/lib/jce.jar</lib>

                        <lib>${java.home}/lib/jsse.jar</lib>

                    </libs>

                    <addMavenDescriptor>false</addMavenDescriptor>

                </configuration>

                <dependencies>

                <dependency>

                   <groupId>net.sf.proguard</groupId>

                   <artifactId>proguard</artifactId>

                   <version>4.8</version>

                   <scope>runtime</scope>

                </dependency>

            </dependencies>

            </plugin>

注意:如果本地服务器Nexus中无proguard-4.8.jar,请从网上下载该Jar包并上传到服务器Nexus.

2   Proguard配置

Proguard分为压缩、优化、混淆三部分:

2.1压缩

-dontshrink 不压缩输入的类文件
-printusage {filename}
-whyareyoukeeping {class_specification}

2.2.优化

-dontoptimize 不优化输入的类文件
-assumenosideeffects {class_specification}
优化时假设指定的方法,没有任何副作用
-allowaccessmodification
优化时允许访问并修改有修饰符的类和类的成员

2.3 混淆

2.3.1 混淆公共配置文件

#不混淆输入的类文件

-dontobfuscate

#打印映射
-printmapping{filename}
#
重用映射增加混淆

-applymapping{filename}

#使用给定文件中的关键字作为要混淆方法的名称

-obfuscationdictionary {filename}

#混淆时应用侵入式重载

-overloadaggressively

#确定统一的混淆类的成员名称来增加混淆
-useuniqueclassmembernames

#重新包装所有重命名的包并放在给定的单一包中
-
flattenpackagehierarchy{package_name}

#重新包装所有重命名的类文件中放在给定的单一包中
-repackageclass {package_name}

#混淆时不会产生形形色色的类名
-dontusemixedcaseclassnames

#保护给定的可选属性
-keepattributes{attribute_name,...}

##保持annotation注释属性,泛型中常用

-keepattributes *Annotation*

#解决泛型问题

-keepattributes Signature

#不去忽略非公共的库类

-dontskipnonpubliclibraryclasses

#不去忽略非公共的库类方法

-dontskipnonpubliclibraryclassmembers

#不预校验

-dontpreverify

#忽略告警,当确定该告警无影响的时候

-dontwarn net.landwind.hip.console.**

#工程中引入的jar

-libraryjars jar包路径,例如:

D:\develop\apache-maven-3.1.1\repository8\org\springframework\spring-core\3.0.3.RELEASE\spring-core-3.0.3.RELEASE.jar

# 保留实现了Serializable接口类中的公有的,友好的,私有的成员(属性和方法)
   # 这个配置主要是对应实体类的配置。
    -
keep publicclass * implements java.io.Serializable{
        public protected private *;
    }

# 枚举类型keep

-keepclassmembers enum * {

   public static **[] values();

   public static ** valueOf(java.lang.String);

}

#保留方法名

-keepclassmembers class * {

   public <methods>;

   protected <methods>;

}

# 保留有该方法的类和该方法

-keepclasseswithmembers class XXX

-keepclasseswithmembers public class * {

public static voidmain(java.lang.String[]);

}

# 类似bean注入需要keep set 和 get 方法

-keepclassmembers public class * extendsXXX{

   void set*(***);

  *** get*();

}

2.3.2    Spring工程公共配置

-keep class javax.servlet.jsp.jstl.** {*; }

-dontwarn javax.servlet.jsp.jstl.*

 

-keep class * extendsjavax.servlet.http.HttpServlet

-keep class * implementsjavax.servlet.ServletContext { *; }

 

-keepclassmembers class * implementsjava.io.Serializable {

   static final long serialVersionUID;

   private static final java.io.ObjectStreamField[] serialPersistentFields;

   !static !transient <fields>;

   private void writeObject(java.io.ObjectOutputStream);

   private void readObject(java.io.ObjectInputStream);

   java.lang.Object writeReplace();

   java.lang.Object readResolve();

}

 

 

-keep class org.dom4j.**  { *; }

#-keep classjavax.jdo.datastore.DataStoreCache

-keep class  org.apache.ws.commons.schema.** { *; }

-keep class  javax.xml.** { *; }

-keep class  org.apache.xml.serializer.** { *; }

-keep class  org.apache.ws.** { *; }

-keep class  com.ibm.wsdl.** { *; }

-keep class  javax.wsdl.** { *; }

 

 

-keep class org.springframework.jndi.JndiPropertySource

-keep classorg.springframework.jndi.JndiLocatorDelegate { *; }

-keep classorg.springframework.context.** { *; }

-keep classorg.springframework.format.support.** { *; }

-keep classorg.springframework.ui.context.support.** { *; }

-keep classorg.springframework.validation.** { *; }

-keep classorg.springframework.http.**  { *; }

-keep classorg.springframework.ui.velocity.** { *; }

-keep classorg.springframework.web.bind.** { *; }

-keep class org.springframework.web.context.**{ *; }

-keep classorg.springframework.web.context.ContextLoaderListener { *; }

-keep classorg.springframework.web.context.support.XmlWebApplicationContext { *; }

-keep class org.springframework.web.context.support.GenericWebApplicationContext{ *; }

-keep classorg.springframework.web.context.support.StaticWebApplicationContext { *; }

-keep classorg.springframework.web.context.support.AbstractRefreshableWebApplicationContext{ *; }

-keep classorg.springframework.web.context.WebApplicationContext { *; }

-keep classorg.springframework.web.filter.** { *; }

-keep classorg.springframework.web.servlet.i18n.**

-keep classorg.springframework.web.method.** { *; }

-keep class org.springframework.web.servlet.DispatcherServlet{ *; }

-keep classorg.springframework.web.servlet.config.**

-keep classorg.springframework.web.servlet.support.*

-keep classorg.springframework.web.servlet.theme.**

-keep classorg.springframework.web.servlet.view.*

-keep classorg.springframework.web.servlet.view.x**

-keep classorg.springframework.web.servlet.view.velocity.**  { *; }

-keep classorg.springframework.web.util.** { *; }

-keep classorg.springframework.web.view.*

-keep class * implements org.springframework.web.context.ConfigurableWebApplicationContext{ *; }

-keep class * implementsorg.springframework.context.ApplicationListener { *; }

-keep class * extendsorg.springframework.web.context.support.XmlWebApplicationContext { *; }

-keep class * implementsorg.springframework.web.bind.support.WebArgumentResolver { *; }

-keep class  org.springframework.core.MethodParameter {*;}

 

-keep class * extendsorg.springframework.web.servlet.DispatcherServlet { *; }

-keep classorg.springframework.beans.factory.** { *; }

-keep classorg.apache.velocity.runtime.directive.** { *; }

-keep classorg.apache.velocity.runtime.ParserPoolImpl

-keep class org.reflections.spring.**

-keep class * implementsjavax.servlet.FilterChain { *; }

 

 

-keepclassmembers class * {

   @org.springframework.beans.factory.annotation.Autowired *;

   @org.springframework.beans.factory.annotation.Qualifier *;

   @org.springframework.beans.factory.annotation.Value *;

   @org.springframework.beans.factory.annotation.Required *;

   @org.springframework.context.annotation.Bean *;

   @javax.annotation.PostConstruct *;

   @javax.annotation.PreDestroy *;

   @org.aspectj.lang.annotation.AfterReturning *;

   @org.aspectj.lang.annotation.Pointcut *;

   @org.aspectj.lang.annotation.AfterThrowing *;

   @org.aspectj.lang.annotation.Around *;

   @javax.jws.WebParam *;

   @javax.jws.WebService *;

}

-keep@org.springframework.stereotype.Service class *

-keep@org.springframework.stereotype.Controller class *

-keep @org.springframework.stereotype.Componentclass *

-keep@org.springframework.stereotype.Repository class *

-keep@org.springframework.cache.annotation.EnableCaching class *

-keep@org.springframework.context.annotation.Configuration class *

-keep@org.springframework.web.bind.annotation.RequestMapping class *

-keep@org.springframework.web.bind.annotation.RequestMethod class *

-keep@org.springframework.web.bind.annotation.RequestParam class *

-keep@org.springframework.web.bind.annotation.ResponseBody class *

-keep @org.springframework.web.bind.annotation.PathVariableclass *

 

-keep @javax.jws.WebParam class *

-keep @javax.jws.WebService class *

            

 

 

-keep classorg.apache.commons.collections.ExtendedProperties { *; }

-keep class org.apache.commons.collections.map.LRUMap{ *; }

-keep classorg.apache.commons.lang.StringUtils { *; }

-keep classorg.apache.commons.lang.text.StrBuilder { *; }

-keep classorg.apache.commons.logging.Log { *; }

-keep classorg.apache.commons.lang.StringEscapeUtils { *; }

2.3.3 工程自定义配置及需要注意的地方

   1.在配置文件中配置的实体类或者在JSP页面中用到的实体对象不要进行混淆;

   2.在配置文件中配置了的类,类名不要混淆,其内部方法和变量可以进行混淆;

   3.添加了配置文件的接口的实现类,接口可以进行完全混淆,只需要保留bean注入的set方法即可;

   4.在配置文件中用到了类的初始化方法或者其他方法,在混淆时要保留,例如:

-keep class com.console.shiro.service.AuthServiceImpl {voidset*(***); java.lang.String loadFilterChainDefinitions();}

保留了bean注入的set方法和在配置文件里使用的loadFilterChainDefinitions()方法。

5.使用了Spring注解的接口,其类名和接口名和方法不能进行混淆;

6.Controller中使用参数注解的要带上名称,例如:

@PathVariable(value="path") String path则要带上(value="path")如果只使用注解不带上参数指定的名称,在混淆之后就会发生空指针异常;同样在@RequestBean("chMedicine")ChMedicinechMedicine,

@RequestParam("actionType")String actionType

实体bean注解和请求参数注解时要带上参数的名称;

 

7.一些辅助工具类的方法和类名也可以全部进行混淆,如果在配置文件中用到则不能混淆类名,各工程可以根据自身需求进行过滤混淆。

8.混淆整个类,类名除外:

-keep class com.console.core.GlobalContext

9.混淆整个类,set*()方法不进行混淆:

-keep class com.console.core.GenericServiceImpl {void set*(***);}

10.混淆类保留公共方法:

-keep class  com.console.standards.dao.ChDiseaseMapper  {public <methods>;}

11.保留类里面的某个方法:

-keep class com.console.shiro.service.AuthServiceImpl { java.lang.StringloadFilterChainDefinitions();}

12.混淆整个包,但是不混淆类名:

 -keepclass com.console.standards.dao.impl.**

13.不混淆包下面的任何东西

-keep class com.console.standards.dao.impl.** {*;}

14.不混淆集成某个类的子类

-keep class * extendsjavax.servlet.http.HttpServlet

15.不混淆实现某个接口的子类

-keep class * implementsjavax.servlet.ServletContext { *; }

16.不混淆某个类的字段

-keep class com.console.core.web.**{<fields>;}

建议如果要很好的将DAOService层进行混淆,尽量少使用注解。

此处只列出了部分常用混淆配置,其他配置根据各自工程需求进行添加。

 

3.工程搭建

3.1.Jar工程混淆

   创建普通的Maven工程,及最终打包为Jar的工程,添加Proguard与maven集成的配置文件,配置见proguard与maven集成章节。

  在pom.xml同级目录下添加proguard.conf配置文件,在此文件中添加对工程的混淆约束及文件过滤配置文件。

 清理工程: mvn clean

  打包命令: mvn package

  部署到本地命令: mvn  install

  部署到服务器命令:mvn deploy

 以上命令可以同时使用,

例如:mvn  clean  package install  deploy则是将上面四步一次性进行处理。

3.2.WEB工程混淆

 由于目前研究的Proguard技术暂时还未解决对WEB工程的混淆技术,因此将WEB工程拆分为两个工程再进行混淆。

3.2.1 分解工程(Jar工程)

 将原始WEB工程console的Java代码及其配置文件全部拷贝到一个新的Jar工程console-lib(当然也是maven工程),文件包名、类名全部保持不变,POM.xml文件的配置与原始Console工程一样,只需修改工程名称为console-lib及打包的类型为jar,

<groupId>com.console</groupId>

 <artifactId>console-lib</artifactId>

 <packaging>jar</packaging>

 <version>1.0.0</version>

 <name>MavenWebapp Archetype</name>

  <url>http://maven.apache.org</url>

 

修改<plugins></plugins>中的打包插件为

<plugin>

            <groupId>org.apache.maven.plugins</groupId>

            <artifactId>maven-jar-plugin</artifactId>

            <executions>

                <execution>

                   <id>make-jar</id>

                   <phase>package</phase>

                   <goals>

                      <goal>jar</goal>

                   </goals>

                   <configuration>

                      <includes>

                         <include>**/console/**</include>

                         <include>**/**/*.xml</include>

                         <include>**/**/*.properties</include>

                      </includes>

                      <excludes>

                        <exclude>spring*.xml</exclude>

                      </excludes>

                   </configuration>

                </execution>

            </executions>

         </plugin>

 

再添加proguard与maven的集成配置,配置见proguard与maven集成章节。

  在pom.xml同级目录下添加proguard.conf配置文件,在此文件中添加对工程的混淆约束及文件过滤配置文件。

打包命令同Jar工程混淆打包命令。

 

3.2.2 分解工程(WEB工程)

  删掉java代码及配置文件,保留Spring加载的公共配置文件,具体配置根据各个工程而定。此时,工程中指剩下前端页面文件。

在web.xml中修改要初始化console-lib工程中的配置文件的,修改如下:

<context-param>

       <param-name>contextConfigLocation</param-name>

       <param-value>

        /WEB-INF/classes/**/spring*.xml

        </param-value>

    </context-param>

修改为:

<context-param>

       <param-name>contextConfigLocation</param-name>

       <param-value>

        /WEB-INF/classes/**/spring*.xml,

        classpath*:com/console/common/spring.xml,

        classpath*:com/console/standards/spring.xml,

        classpath*:com/console/sys/spring.xml,

        classpath*:com/console/sys/person/spring.xml

        </param-value>

    </context-param>

   在pom.xml文件中添加console-lib.jar的依赖:

<dependency>

        <groupId>com.console</groupId>

       <artifactId>console-lib</artifactId>

        <version>1.0.0</version>

      </dependency>

开发时需要将console和console-lib工程放在同一个工作空间,可以在console-lib工程中进行断点Debug;打包混淆好的console工程,必须先将console-lib工程部署到本地,或者部署到服务器,要保证本地和服务器的console-lib是混淆后的最新版本。

Console工程和console-lib工程在同一工作空间时,运行console WEB工程时无需再引入console-lib工程,只需将console-lib工程打开即可。只需要运行console WEB工程一个就行。

Proguard混淆与Maven集成

混淆之后的Java代码

Proguard混淆与Maven集成