天天看點

代碼混淆技術yguard、ProGuard、Allatori

混淆

Java的bytecode很容易通過JAD等反編譯工具還原出源代碼。這樣勢必不滿足安全的定義。如何一定程度上保護需要防止被反編譯的源代碼呢?混淆(obfuscate)技術。注意:用obfuscate防盜版是根本不可能,連彙編這種東西都能被破解掉,而java代碼基本上等同于開源的同義詞。用obfuscate隻是為了增加反編譯的難度,保護源代碼的知識産權。混淆包照常運作,沒有任何問題。可以使用反編譯工具如jd-gui檢視混淆後的包,驗證混淆效果。

下面對Java中的幾個混淆器​​​obfuscator​​進行簡介。

混淆技術

名稱混淆

即 name Obfuscation,将有意義的類,字段、方法名稱更改為無意義的字元串。生成的新名稱越短,位元組代碼越小。在名稱混淆的位元組代碼中,包,類,字段和方法名稱已重命名,并且永遠不能恢複原始名稱。不幸的是,控制流程仍然清晰可見。故而需要Flow Obfuscation,流混淆。

流混淆

Flow Obfuscation,用于​

​if, switch, while,for​

​等關鍵字,對位元組碼進行細微的修改,模糊控制流,而不改變代碼在運作時的行為。通常情況下,選擇和循環等邏輯構造會被更改,是以它們不再具有直接等效的Java源代碼。流模糊的位元組碼通常強制反編譯器将一系列标簽和非法的goto語句插入到它們生成的源代碼中。源代碼有時會因為反編譯錯誤而變得更加模糊。

異常混淆

​​Exception Obfuscation​​,與流混淆類似,作用于異常。

字元串加密混淆

​​String Encryption​​

引用混淆

​​Reference Obfuscation​​

yguard

對yguard不會詳細論述太多,僅僅隻是為了說明混淆的一些概念、術語和技術手段等,因為推薦選擇proguard。

​​​yguard官網​​​​yguard_ant_howto​​

介紹

一個java類檔案模糊器,官網下載下傳得到一個jar檔案,沒有找到maven dependency GAV;使用之前需要確定系統配置好ant,通過antrun的方式,即build.xml檔案來配置Task。這一點實在是落後。

把生成的class檔案打包成jar檔案,然後對jar檔案進行模糊化;還能夠通過分析源碼,移除未使用的類、方法、屬性等;較小jar檔案。可以完成以下模糊化工作:模糊化方法以及類中的變量名、方法名、類名、包路徑,去除class檔案中的調試資訊等等。對模糊化類的成員變量名、方法名、類名,可以分别設定保護級别。設定的修飾符和java的修飾(通路控制)符一緻,包括:public、protected、private、none。以保護方法名為例

  • public: 表示除public的方法名不需要混淆外,模糊化其他所有的方法名(protected和private)
  • protected: 表示除public和protected的方法名不進行混淆,其餘方法名都要進行模糊化(private)
  • private: 表示對方法名不進行混淆
  • none: 表示對所有方法名均進行模糊化
<expose>
  <class classes="public" methods="public" ields="public"/>
</expose>      

混淆後的效果:

代碼混淆技術yguard、ProGuard、Allatori

生成的jar包裡面的MANIFEST.MF檔案:

安全考慮,混淆技術;
MANIFEST.MF檔案:
Class-Path: . bcprov-jdk14-150.jar
Ant-Version: Apache Ant 1.8.2
Created-By: yGuard Bytecode Obfuscator 2.5.2
Main-Class: SoftEncExchange
Name: A/A/A/A/A.class
SHA-1-Digest: rTJ++qML61cQW+9pghvdpI4LyjA=
Digest-Algorithms: SHA-1, MD5
MD5-Digest: 40phkXrhaJlsqjAhNzztTg==      

其他更多配置,參考​​yguard_ant_howto​​

ProGuard

​​ProGuard官網​​ ProGuard,一款shrinker(壓縮:檢測和删除沒有使用的類,字段,方法和屬性), optimizer(優化:對位元組碼進行優化,并且移除無用指令), obfuscator(混淆:使用a,b,c等無意義的名稱,對類,字段和方法進行重命名), and preverifier(稽核:在Java平台上對處理後的代碼進行預檢)工具。

簡單使用

從這裡​​​下載下傳​​得到最新版6.0.3,首先看readme,解壓縮之後得到的諸多目錄,隻需關注bin,docs,lib,examples,其他目錄是源碼和腳本檔案。

Allatori

​​Allatori官網​​​ Allatori,第二代Java混淆器。所謂​​第二代混淆器​​,不僅僅能進行字段混淆,還能實作流混淆。

Allatori does not just obfuscate, it also minimizes application size, and boosts the speed, has full watermark functionality.

Allatori有以下幾種混淆方式:命名混淆,流混淆,調試資訊混淆,字元串混淆,及水印技術。可免費用于教育和非商業項目。支援war和jar格式,支援對需要混淆代碼的應用程式添加有效日期。

入門

沒有找到allatori的maven GAV,需要去官網下載下傳 allatori.jar,放置在項目的根目錄下,或安裝到本地Maven倉庫,或上傳到内網的Nexus私服倉庫。

pom.xml配置:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-resources-plugin</artifactId>
    <version>3.1.0</version>
    <executions>
        <execution>
            <id>copy-and-filter-allatori-config</id>
            <phase>package</phase>
            <goals>
                <goal>copy-resources</goal>
            </goals>
            <configuration>
                <outputDirectory>${basedir}/target</outputDirectory>
                <resources>
                    <resource>
                        <directory>${basedir}/allatori</directory>
                        <includes>
                            <include>allatori.xml</include>
                        </includes>
                        <filtering>true</filtering>
                    </resource>
                </resources>
            </configuration>
        </execution>
    </executions>
</plugin>
<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>1.6.0</version>
    <executions>
        <execution>
            <id>run-allatori</id>
            <phase>package</phase>
            <goals>
                <goal>exec</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <executable>java</executable>
        <arguments>
            <argument>-Xms128m</argument>
            <argument>-Xmx512m</argument>
            <argument>-jar</argument>
            <argument>${basedir}/lib/allatori.jar</argument>
            <argument>${basedir}/target/allatori.xml</argument>
        </arguments>
    </configuration>
</plugin>      
<config>
    <input>
        <jar in="demo-0.0.1-SNAPSHOT.jar" out="demo-0.0.1-SNAPSHOT-obfuscated.jar"/>
    </input>
    <keep-names>
        <class access="protected+">
            <field access="protected+"/>
            <method access="protected+"/>
        </class>
    </keep-names>
    <property name="log-file" value="log.xml"/>
</config>      

選擇

  • 是否開源,以及活躍度,Google的搜尋指數如何
  • 速度
  • 效率
  • 是否支援包名obfuscate
  • 是否支援增量obfuscate
  • 對資源、配置檔案的混淆,如jdbc.properties

參考

  • ​​Java後端代碼混淆應用實踐​​
  • ​​使用Java混淆工具yguard​​
  • ​​ProGuard詳解​​
  • ​​ProGuard學習筆記​​