使用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的博客
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章