java代碼混淆


僅做記錄之用。  

  java代碼可以反編譯,因此有時候要保護自己的知識產權還真得費點心思,一般來說有三個思路:
  1、將class文件加密,這個是最安全的,但也費事兒,因為要重寫classloader來解密class文件;
  2、使用花指令,使得class文件不能反編譯(利用反編譯工具漏洞);安全性一般,還是有花指令破解器;
  3、代碼混淆,提高代碼閱讀成本;簡單易操作,一般采用這種或者與其它方式結合;
  我們項目中用到的即為代碼混淆工具ProGuard,相關文章參考:
  ProGuard是一個純java編寫的混淆工具,有客戶端跟jar包兩種使用方式。可以將程序打包為jar,然后用工具進行混淆,也可以在maven中導入ProGuard的插件,對代碼進行混淆。本例中為對普通javaweb項目進行代碼混淆。maven配置插件如下:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<!-- ProGuard混淆插件-->
< plugin >
    < groupId >com.github.wvengen</ groupId >
    < artifactId >proguard-maven-plugin</ artifactId >
    < version >2.0.11</ version >
    < executions >
       < execution >
          <!-- 混淆時刻,這里是打包的時候混淆-->
          < phase >package</ phase >
          < goals >
             <!-- 使用插件的什么功能,當然是混淆-->
             < goal >proguard</ goal >
          </ goals >
       </ execution >
    </ executions >
    < configuration >
       <!-- 是否將生成的PG文件安裝部署-->
       < attach >true</ attach >
       <!-- 是否混淆-->
       < obfuscate >true</ obfuscate >
       <!-- 指定生成文件分類 -->
       < attachArtifactClassifier >pg</ attachArtifactClassifier >
       < options >
          <!-- JDK目標版本1.8-->
          < option >-target 1.8</ option >
          <!-- 不做收縮(刪除注釋、未被引用代碼)-->
          < option >-dontshrink</ option >
          <!-- 不做優化(變更代碼實現邏輯)-->
          < option >-dontoptimize</ option >
          <!-- 不路過非公用類文件及成員-->
          < option >-dontskipnonpubliclibraryclasses</ option >
          < option >-dontskipnonpubliclibraryclassmembers</ option >
          <!--不用大小寫混合類名機制-->
          < option >-dontusemixedcaseclassnames</ option >
 
          <!-- 優化時允許訪問並修改有修飾符的類和類的成員 -->
          < option >-allowaccessmodification</ option >
          <!-- 確定統一的混淆類的成員名稱來增加混淆-->
          < option >-useuniqueclassmembernames</ option >
          <!-- 不混淆所有包名-->
          <!--<option>-keeppackagenames</option>-->
 
          <!-- 需要保持的屬性:異常,注解等-->
          < option >-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod</ option >
          <!-- 不混淆所有的set/get方法->
          <!--<option>-keepclassmembers public class * {void set*(***);*** get*();}</option>-->
 
          <!-- 不混淆包下的所有類名,且類中的方法也不混淆-->
          < option >-keep class com.xxx.xxx.bboss.SystemConfig { < methods >; }</ option >
          < option >-keep class com.xxx.xxx.framework.** { *; }</ option >
          < option >-keep class com.xxx.xxx.xxx.controller.** { < methods >; }</ option >
          < option >-keep class com.xxx.xxx.xxx.dao.** { < methods >; }</ option >
          < option >-keep class com.xxx.xxx.xxx.exception { < methods >; }</ option >
          < option >-keep class com.xxx.xxx.xxx.model.** { < methods >; }</ option >
 
       </ options >
       <!--class 混淆后輸出的jar包-->
       < outjar >classes-autotest.jar</ outjar >
       <!-- 添加依賴,這里你可以按你的需要修改,這里測試只需要一個JRE的Runtime包就行了 -->
       < libs >
          < lib >${java.home}/lib/rt.jar</ lib >
       </ libs >
       <!-- 對什么東西進行加載,這里僅有classes成功,畢竟你也不可能對配置文件及JSP混淆吧-->
       < injar >classes</ injar >
       <!-- 輸出目錄-->
       < outputDirectory >${project.build.directory}</ outputDirectory >
    </ configuration >
</ plugin >

  運行 mvn clean package -DskipTests

  混淆后結果如圖所示:
  classes-pg.jar為混淆后的classes文件,里邊包含完整的項目結構
  proguard_map.txt混淆內容映射
  proguard_seed.txt參與混淆的類
  混淆后反編譯代碼如下:
 
  可以看到,部分包名跟類名已經被改為了簡單字母,不再具有業務含義,而且變量名也進行了修改,增加了閱讀代碼難度。
  運行服務,項目正常運行。
  需要注意的問題:
  1、因為有時候會配置不保持包名或類名,因此一些相關配置文件的內容需要改變,好在ProGuard不是隨機生成類名,而是先按照原名稱對相同包下類進行排序,混淆后的類名稱依次為a.class,b.class,c.class.....
那么問題來了,當包中超過26個類時,默認命名為A.class,B.class,C.class,在某些操作系統下,會不區分class文件名稱的大小寫,會導致錯誤(水平所限,未深入探究跟類加載相關);因此
  <!--不用大小寫混合類名機制-->
  <option>-dontusemixedcaseclassnames</option>
  配置極為關鍵,該配置會在超過26個類文件時,命名為aa.class,ab.class,ac.class,而不是原來的大寫類名,從而避免錯誤。
  2、打包部署問題。該配置文件打包出來的war中classes文件仍然為正常代碼,需要手動解壓,將classes-pg.jar中classes替換進去,在工程化管理的情況下,可以在jenkins中配置腳本,自動將混淆后的classes替換進war包:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#更改war包classes為混淆包的內容
cd /root/ .jenkins /workspace/mytest_master/target
jar -xvf classes-pg.jar
rm -rf mytest
mkdir mytest
mv mytest.war mytest
cd mytest/
jar -xvf mytest.war
rm -rf WEB-INF /classes/com/
cd ../
 
cp -rf com mytest /WEB-INF/classes/
cd mytest
jar -cvfM0 mytest.war ./
mv mytest.war ../
這樣jenkins打出的就是混淆后的war包了,可以直接交給客戶使用。

 
 
 
 
 


免責聲明!

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



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