java、springboot使用proguard混淆代碼


1.情景展示

  我的需求是:為了將項目部署到機器上時,既不影響項目的正常運行,又可以做到降低項目源碼(class文件)的可讀性,其主要目的是為了防盜。

  一般情況下是用不到混淆器的,但是實際生活中往往存在這樣的問題或需求,比方說:由於時間緊迫,兩家企業被迫聯合共同上線一個產品,現在是雖是合作關系,他們又可以相互取締,同樣的市場,蛋糕就這么大,時間長了難免互生嫌隙,所以為了保護各自產品被竊取,就需要防盜神器proguard了。

2.proguard簡介

ProGuard 是一個免費的 Java類文件的壓縮,優化,混餚器。它刪除沒有用的類,字段,方法與屬性。使字節碼最大程度地優化,使用簡短且無意義的名字來重命名類、字段和方法 。eclipse已經把Proguard集成在一起了。

  吐槽:但說句實在話,proguard雖然降低了代碼的可讀性,但是,仍是能夠讀懂的,只是費點勁罷了。正所謂:防君子不防小人。

3.proguard教程

  第一步:maven配置(pom.xml)

<!--構建工具-->
<build>
    <!--自定義打包后的項目名稱
    可以無視默認的打包名稱規則:${artifactId}-${version}-->
    <finalName>bill</finalName>
    <plugins>
        <!--maven編譯插件-->
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <!--二選一-->
            <version>${spring.version}</version>
            <!--<version>2.3.1.RELEASE</version>-->
        </plugin>
        <!--java混淆器插件-->
        <plugin>
            <groupId>com.github.wvengen</groupId>
            <artifactId>proguard-maven-plugin</artifactId>
            <version>2.3.1</version>
            <executions>
                <execution>
                    <!-- 混淆時刻:這里是打包的時候混淆 -->
                    <phase>package</phase>
                    <goals>
                        <!-- 使用插件的什么功能: 混淆-->
                        <goal>proguard</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <proguardVersion>${proguard.version}</proguardVersion>
                <!--<proguardVersion>6.2.2</proguardVersion>-->
                <!-- 是否混淆-->
                <obfuscate>true</obfuscate>
                <!--關鍵:引入配置文件,這里換成你的配置文件所在路徑,一般情況下就是把proguard.cfg放到這個目錄-->
                <proguardInclude>${project.basedir}/src/main/resources/proguard.cfg</proguardInclude>
                <!-- 混淆時需要引用的java庫,這些庫的類不會做混淆 -->
                <libs>
                    <lib>${java.home}/lib/rt.jar</lib>
                    <lib>${java.home}/lib/jce.jar</lib>
                </libs>

                <!--當<injar></injar>的值為:classes時,可以結合該標簽使用,作用:相關混淆配置只為指定目錄下的class文件起效-->
                <!--<inFilter>com/marydon/**</inFilter>-->
                <!-- 需要做混淆的jar或class目錄,也就是:選擇對什么東西進行加載-->
                <injar>classes</injar>
                <!--<injar>${project.build.finalName}.jar</injar>-->

                <!--class 混淆后輸出的jar包,說明:這個輸出格式可有可無,下面會講 -->
                <outjar>${project.build.finalName}-pd.jar</outjar>
                <!-- 輸出目錄 -->
                <outputDirectory>${project.build.directory}</outputDirectory>
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>net.sf.proguard</groupId>
                    <artifactId>proguard-base</artifactId>
                    <version>${proguard.version}</version>
                    <!--<version>6.2.2</version>-->
                    <scope>runtime</scope>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
 </build>

  這里需要注意的一點是:build標簽需要在dependencies下方

  第二步:插件下載

  先不要管proguard.cfg文件怎么寫,搞定這個插件才能繼續往下走,不然就是浪費時間,即使你將配置文件寫好,離開了這個插件,要配置文件有啥用?

  為了搞定最新版的插件,浪費了我不少時間,下面科普一下,如果你引入以上配置文件后,proguard插件下載成功,就可以跳過這一步了。

  上面這個插件,明確的告訴你:阿里雲maven中央倉庫有!!!

  如果下載失敗,說明:該項目使用的maven中央倉庫不是阿里雲的,怎么辦?

  很簡單,不用去該maven下面的settings.xml,直接在項目中引入即可。

 <!--配置項目的jar包倉庫-->
<repositories>
    <!--阿里雲倉庫,id=central,會覆蓋掉setting.xml中配置的中央倉庫-->
    <repository>
        <id>central</id>
        <name>central maven</name>
        <url>https://maven.aliyun.com/repository/central</url>
        <!--<url>http://maven.aliyun.com/nexus/content/groups/public/</url>-->
    </repository>
    <!--maven官網-->
    <repository>
        <id>public</id>
        <name>public maven</name>
        <url>https://mvnrepository.com</url>
    </repository>
</repositories>

  這樣,倉庫配置僅對本項目生效,也不會影響到其它項目對於settings.xml的依賴。

  這里需要注意的一點是:repositories標簽需要在dependencies上方

  點擊右側maven視圖里的這個按鈕,網絡較好的情況下,很快就下載完成了。

  如果插件不再報錯,基本上就成了 

  如果該插件下載不成功,就沒有繼續進行下去的必要了,等搞定再往下看。

  第三步:proguard.cfg配置文件

  新建proguard.cfg文件,並將其放到src/main/resources目錄下

  第四步:打包

  使用maven插件打包,打開maven視圖,找到package,進行打包即可。

  打包成功日志 

  成功后,target目錄下會多出三個文件 

  bill-pd.jar,就是項目混淆后的jar包(

  也就是說:混淆后的代碼會被proguard插件單獨打成一個jar包,與bill.jar的主要區別就是:前者是帶有混淆的class文件,后者是正常的class文件

 

  這里,講一下前面在pom.xml中配置的<outjar>${project.build.finalName}-pd.jar</outjar>標簽,這個標簽可有可無。

  如果去掉指定混淆文件的輸出格式,打包后會是什么樣的呢?

  區別在於:原來的bill-pd.jar變成了classes_proguard_base目錄

  里面的內容沒有區別。

  第五步:injar與outjar

  這兩個標簽如果不配合好,效率將會大打折扣,而且還容易出錯。由上面我們知道,

  injar:是在插件混淆的源目錄,也就是,混淆前的代碼來源,它有兩種表現形式:第一種是class目錄,第二種是${project.build.finalName}.jar;

  outjar:插件執行混淆完畢后,將要輸出的文件打包成什么樣的格式,這里僅支持jar包,不支持war包,injar標簽也一樣;如果不聲明該標簽的話,將會默認生成classes_proguard_base目錄。

  第六步:部署項目

  方式一:部署jar包

  編譯源目錄格式使用:<injar>${project.build.finalName}.jar</injar>

  輸出目錄格式使用:<outjar>${project.build.finalName}-pd.jar</outjar>

  這樣,即使沒有前后端分離,我們也可以確保bill-pd.jar包含的是項目的完整代碼,可以拿出直接使用

  測試結果如下:

  可能會報這個錯:Unable to open nested entry ********.jar

  分析:因為javaUtils.jar是我自己封裝的一個jar包,混淆插件會將它單獨抽出來再次壓縮,導致java解析失敗,所以我就想將輸入輸出名字保持一致。 

  測試結果如下:

  使用將輸出的jar包名稱和輸入jar包名稱保持一致

  即:<outjar>${project.build.finalName}.jar</outjar>,其執行結果是:生成的默認值(項目名稱_proguard_base.jar)

  項目啟動成功,但仍無法訪問項目,這個問題是idea maven插件自身package命令的bug

  解決方案,就是使用原始的maven命令,手動將其打成jar包,不懂的可以見文末推薦

  項目訪問成功(<outjar>${project.build.finalName}.jar</outjar>,必須是這個)

  方式二:部署war包

  編譯源目錄格式使用:<injar>classes</injar>

  輸出目錄格式使用:刪除<outjar></outjar>標簽

  打包標簽設置成war:<packaging>war</packaging>

  將項目打成war包后,用壓縮軟件打開,依次打開WEB-INF/classes目錄,刪掉,再將生成的混淆文件里的class文件復制進去即可。

   

 

寫在最后

  哪位大佬如若發現文章存在紕漏之處或需要補充更多內容,歡迎留言!!!

 相關推薦:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM