天天看點

使用Proguard混淆Spring Boot項目代碼

項目中需要對代碼進行混淆處理,由于項目是标準的maven項目,便使用了

proguard-maven-plugin

來自動化混淆過程,但是在使用過程中也不免踩到了一些坑,網上也很少有提及,在此記錄一下。

踩過的坑

spring bean名稱沖突問題

預設proguard混淆後的類名類似a.class,b.class,但是不同包路徑下類名可能發生重名,在spring中預設會把類名作為bean的名稱,導緻會報spring bean名稱沖突的問題,可以通過重新實作

BeanNameGenerator

接口來解決:

@SpringBootApplication
@ComponentScan("com.abc.def")
public class Application {

    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class)
                .beanNameGenerator(new CustomBeanNameGenerator())
                .run(args);
    }

    private static class CustomBeanNameGenerator implements BeanNameGenerator {
        @Override
        public String generateBeanName(BeanDefinition d, BeanDefinitionRegistry r) {
            return d.getBeanClassName();
        }
    }
}           

spring擷取不到jar包裡的包路徑

spring boot啟動後實作

ApplicationRunner

接口的初始化類并沒有執行,也沒有錯誤日志産生。後來把spring容器注冊的Bean列印出來發現除了入口類和spring自己的類都沒有加載。spring啟動debug模式并調整日志級别為

TRACE

,發現spring沒有解析出包含basePackage的jar包來,假設basePackage為

com/abc/def/

,不混淆代碼的日志如下:

2019-11-24 19:33:49.703 [TRACE] [main] [o.s.c.i.s.PathMatchingResourcePatternResolver : 323] Resolved classpath location [com/abc/def/] to resources [URL [jar:file:/tmp/foo/lib/service-facade-1.0.jar!com/abc/def/], URL [jar:file:/tmp/foo/lib/service-impl-1.0.jar!com/abc/def/]]           

經proguard混淆後日志如下:

2019-11-24 19:33:49.703 [TRACE] [main] [o.s.c.i.s.PathMatchingResourcePatternResolver : 323] Resolved classpath location [com/abc/def/] to resources []           

但是将混淆後jar包先解壓後再壓縮處理,卻可以正常加載。也就是說proguard在打包過程中把包路徑資訊丢失了。需要配置

keepdirectories

參數。

JDK9編譯的jar包類沖突

JDK9編譯出來的jar包會和一些類沖突,需要配置

inLibsFilter

排除掉。

多jar包混淆

預設

proguard-maven-plugin

插件隻能通過

injar

參數将一個jar包混淆,而常見的項目都是多子產品項目,這時就需要通過配置

assembly

參數來實作。

參考配置

Pom.xml:

<plugin>
  <groupId>com.github.wvengen</groupId>
  <artifactId>proguard-maven-plugin</artifactId>
  <version>2.2.0</version>
  <executions>
    <execution>
      <id>release</id>
      <phase>package</phase>
      <goals>
        <goal>proguard</goal>
      </goals>
      <configuration>
        <assembly>
          <inclusions>
            <inclusion>
              <groupId>com.abc.def</groupId>
              <artifactId>lib1</artifactId>
            </inclusion>
            <inclusion>
              <groupId>com.abc.def</groupId>
              <artifactId>lib2</artifactId>
            </inclusion>
          </inclusions>
        </assembly>
        <!--exclude jdk9-->
        <inLibsFilter>!META-INF/versions/9/**.class</inLibsFilter>
        <proguardInclude>proguard.conf</proguardInclude>
        <libs>
          <lib>${java.home}/lib/rt.jar</lib>
          <lib>${java.home}/lib/jce.jar</lib>
        </libs>
        <!--<silent>true</silent>-->
      </configuration>
    </execution>
  </executions>
  <dependencies>
    <dependency>
      <groupId>net.sf.proguard</groupId>
      <artifactId>proguard-base</artifactId>
      <version>6.2.0</version>
    </dependency>
  </dependencies>
</plugin>           

proguard.conf:

-dontshrink
-dontoptimize
-keepdirectories
-adaptclassstrings
-dontusemixedcaseclassnames
-flattenpackagehierarchy 'com.abc.def'
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod

-keep class com.abc.def.Application
-keep class * extends org.springframework.boot.ApplicationRunner

# Keep - Applications. Keep all application classes, along with their 'main'
# methods.
-keepclasseswithmembers public class * {
    public static void main(java.lang.String[]);
}

# Also keep - Enumerations. Keep the special static methods that are required in
# enumeration classes.
-keepclassmembers enum  * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

# Keep names - Native method names. Keep all native class/method names.
-keepclasseswithmembers,includedescriptorclasses,allowshrinking class * {
    native <methods>;
}           

參考

  1. Proguard官方文檔
  2. proguard-maven-plugin
  3. proguard-spring-boot-example
  4. 基于ProGuard-Maven-Plugin的自定義代碼混淆插件
  5. 解決Proguard5.3版本不支援含有JDK9代碼的Jar包混淆問題
  6. Bug#35 Missing directory entries in jars
  7. yx9190的部落格