整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          前端代碼安全與混淆

          前端代碼安全與混淆

          者:京東零售 周明亮

          一、友商網頁分析

          1.1 亞馬遜

          亞馬遜商詳地址:
          https://www.amazon.com/OtterBox-Commuter-Case-iPhone-Packaging

          • 所有交互事件在頁面初始化時,不進行下發,等待通過 js 請求后下發 具體點擊事件js內容
          • 采用自執行方式,防止代碼格式化?!緹o法調用 Chrome 自帶的代碼格式化工具】
          • 采用自研式框架,非傳統 react / vue / angular。大量通過 data-xx 標簽進行數據傳遞,導致標簽結構較為復雜。

          1.2 淘寶

          主要配合接口進行加密,采用多字段干擾,模板化加載。下發大量的模版數據,之后通過客戶端進行填充。

          客戶端代碼為傳統的普通加密模式

          1.3 拼多多

          • 傳統普通加密方式,使用 React 框架?!居忻黠@的 React 語法糖】
          • 關鍵的商詳數據,需要強制進行登錄操作,可以對賬號進行封禁。

          二、攻擊者角度

          1. [Web逆向] 數某風控JS算法分析 常規網頁加密調式
          2. Crack App | 某 H5 App 反調試對抗 反調式 APP 內 Webview
          3. Puppeteer 融入調試流程,調試體驗爽翻了! 可模擬用戶實際點擊流程,進行流程化操作,此類方式,比較難以區分
          4. Node.js 安全最佳實踐 常見的 Node JS 官方發布的被攻擊類型。
          • 參考:NodeJS 官網指導手冊?
          1. 通過幾行 JS 就可以讀取電腦上的所有數據? 旁路攻擊,通過內存響應速度獲取用戶密碼信息
          2. ?Qwik JS 框架 JS代碼的拆分從常見的「編譯時」(比如webpack分塊)、「運行時」(比如dynamic import),變為「交互時」。只有用戶操作時,才會進行注入加載。
          3. 實踐:天貓汽車商詳頁的SSR改造實踐 天貓汽車商詳頁,改造原理本質上是基于 Qwik JS 。
          4. 聊聊前端安全之CSRF?
          • 非代碼泄漏類,常規類型Web 攻擊,基于代碼破解后
          • XSS攻擊:跨站腳本攻擊(Cross-Site Scripting),攻擊目標是為了盜取存儲在客戶端的cookie或者其他網站用于識別客戶端身份的敏感信息。一旦獲取到合法用戶的信息后,攻擊者甚至可以假冒合法用戶與網站進行交互。
          • CSRF(Cross-site request forgery)跨站請求偽造:攻擊者誘導受害者進入第三方網站,在第三方網站中,向被攻擊網站發送跨站請求。利用受害者在被攻擊網站已經獲取的注冊憑證,繞過后臺的用戶驗證,達到冒充用戶對被攻擊的網站執行某項操作的目的。
          • 網絡劫持攻擊,主要是通過一些代理服務器,或者wifi等有中間件的網絡請求,進行劫持,不法分子通過這種方式獲取到用戶的信息。
          • 控制臺注入代碼,不法分子通過各種提示誘騙用戶在控制臺做一些操作,從而獲取用戶信息。
          • 釣魚攻擊,
          • 電子郵件釣魚:群發郵件,欺騙用戶點擊惡意的鏈接或附件,獲取有價值的信息
          • 網站釣魚:在網站上偽造一個網站,通常是模仿合法的某個網站。為了欺騙用戶點擊這個網站還會采取些輔助技術,比如釣魚郵件、短信、電話
          • 防釣魚
          • SPF記錄,SPF是為了防范垃圾郵件而提出來的一種DNS記錄類型,它是一種TXT類型的記錄,它用于登記某個域名擁有的用來外發郵件的所有IP地址。
          • SafeBrowsing API,谷歌的一個隨時可以通過互聯網訪問的API,允許允許瀏覽器在渲染之前檢測URL的正確性。
          • DDOS:分布式拒絕服務攻擊(Distributed Denial of Service),簡單說就是發送大量請求是使服務器癱瘓
          • SQL注入攻擊,通過對web連接的數據庫發送惡意的SQL語句而產生的攻擊,從而產生安全隱患和對網站的威脅,可以造成逃過驗證或者私密信息泄露等危害
          • 點擊劫持,點擊劫持是指在一個Web頁面中隱藏了一個透明的iframe,用外層假頁面誘導用戶點擊,實際上是在隱藏的frame上觸發了點擊事件進行一些用戶不知情的操作。
          1. AI 介入解釋代碼,加速代碼反編譯進程
          • 比如將友商代碼放入 chatgpt 進行釋義

          這個只是部分代碼,如果將完整代碼,一段一段進行分析,你就可以得到完整上下文,不需要靠人去一段一段讀取代碼。

          目前還有 ai 代碼調試如:
          https://github.com/shobrook/adrenaline?


          三、防御者角度

          1. JS 代碼混淆
          • 應對:普通開發者或者不懂編程的普通用戶。實例:大部分網頁
          • 進行代碼混淆/加密,減少語義化理解。
          • 通過代碼調試,查找特定 DOM 結點,反復斷點調試,即可了解相關執行邏輯
          1. JS 虛擬機
          • 應對:專業編程開發者。實例:暫無
          • 通過 AST 轉換 代碼為二進制碼,再通過虛擬機運行二進制碼。
          • 會導致網頁執行性能變差,執行加載更多 JS 文件
          • 無法進行斷點提示,但是會把解密流程對外暴露。
          • 直接調用 JS 虛擬機,執行最小化JS片段,從而了解整個虛擬機的加密規則。
          1. 強制下載 APP 通過 Webview 打開
          • 應對:中高級編程開發者。實例如:拼多多等
          • H5 代碼只是對外展示數據,關鍵內容提示用戶下載 APP,增加調試難度
          • 用戶不愿意下載APP,就會導致用戶流失。
          1. 接口校驗/字段混淆
          • 應對:Python 爬蟲類,實例如:淘寶、好詞好句網等等
          • 通過接口生成混淆模版,多字段隨機發送,配置相關JS 模版框架。
          • 接口內容傳輸 base64 / aes 加解密處理,但是會留下解密 JS 在客戶端,依舊能夠被破解。
          • Token 強制校驗,發送三次錯誤,直接不在返回數據,需要用戶強制登錄,容易導致用戶流失。
          1. 自定義框架
          • 應對:Python 爬蟲類,中高級編程開發者。實例如:亞馬遜/淘寶。【還需要繼續挖掘】
          • 爬蟲無法第一時間獲取相關按鈕的 API 請求接口,需要等待 JS 返回。
          • 客戶端存在大量無關數據,導致 dom 結點整體看起來無規律
          • JS 通過 接口請求返回,配合相關的 Token 參數,可以達到隨機性下發

          四、結論

          4.1 大部分攻擊者共同點

          1)自身不愿意登錄,或者偷取正常用戶信息后,用于攻擊

          • 如一些外掛程序,免費提供給外部用戶,用戶貪圖小利,以為可以通過外部程序加快搶利
          • 實則被記錄用戶名,給到攻擊者使用。

          2)如果是公司行為,很可能會被記錄IP,有法務風險。

          • 可以分析電腦名稱,IP 地址
          • 可能會進行 IP 服務器代理,采用虛擬 IP,虛擬定位
          • 使用云服務器,如:阿里云 / 京東云,進行攻擊相應的網站,京東云到京東網站。

          3)多次進行嘗試修改 token ,偽裝發送請求

          • 偽造 UA
          • 開啟調試模式

          4)分析 DOM 結構特征 / 使用 Console 打印全局存儲變量

          5)通過 cookies 分析特定的關鍵詞,全局搜索

          6)網絡請求時,查看函數執行棧,逐級往下尋找核心請求函數。

          4.2 應對普通開發者外掛程序

          • 主要采用 puppeteer 就可以完全模擬用戶操作流程,可以進行等待某個節點出現,之后再進行操作,不再需要傳統的代碼調試操作。直接操作 DOM 結點點擊響應
          • 基于此類需求,需要經常變更 DOM 結點位置。增加業務方成本,每次都需要發版。如果是隨機生成結點特征,需要開發自研框架,成本較高

          4.3 應對Pyhton爬蟲

          1)前端代碼采用傳統加密方式

          • https://github.com/mishoo/UglifyJS?
          • https://github.com/terser/terser?
          • ?https://github.com/javascript-obfuscator/javascript-obfuscator
          • 更多傾向于 接口 加密方式,加固加 Token

          2)入口在 APP 內的 業務

          • 本身調試需要需要額外鏈接機器,提高調試復雜度。
          • 配合 APP 自身監控,特定API 可以做到更加安全
          • 也只有此類業務,可以采用 JS 虛擬機方式

          3)對關鍵詞進行混淆處理,減少特征搜索

          • 可采用下面方式,只是舉例,可以有更多方式。比如數組組合,對象組合等等
          • const GLOBAL_SOCKET_NAME='c6on6ne6ct'.concat('S6o').concat('c6ke6t').replace(/6/g, '')
          • 常規代碼混淆中,對完整字符串,不會進行處理,導致會直接暴露關鍵字。


          任何客戶端加密混淆都會被破解,只要用心都能解決,我們能做的就是拖延被破解的時間,而不是什么都不做,那樣只會被破解更快!

          其實很多我們自己公司對外的頁面,都有很多外露風險,包括不規范的日志輸出,直接對外暴露加密的防刷 token。 比如:

          ?大家都可以自查下~

          今互聯網時代,JavaScript已經成為了web前端開發的重點技術之一。其中,JavaScript代碼的安全性問題一直是關注的焦點。為了保護JavaScript代碼的安全性,很多人對其進行加密處理,眾所周知,對于單純的加密算法,通過反向工程或逆向分析也能夠破解。在此情況下,JavaScript代碼混淆技術成為了一種應對加密破解的有效措施。

          一、JS加密算法

          JS加密算法是指JavaScript代碼通過異或加密、Base64加密、MD5加密、SHA1加密等方式對其內容進行加密處理。例如,下面的加密函數中,通過異或運算對字符串進行了加密:

          Copy codefunction encryptByXOR(message, key) {
              var encrypted='';
              for (var i=0; i < message.length; i++) {
                  var c=message.charCodeAt(i) ^ key.charCodeAt(i % key.length);
                  encrypted +=String.fromCharCode(c);
              }
              return encrypted;
          }
          
          var message='Hello world';
          var key='1234567890';
          
          var encrypted_message=encryptByXOR(message, key);
          console.log('加密后的字符串:', encrypted_message);

          通過對源代碼進行加密處理,能夠為JavaScript代碼的安全性提供一定的保障。不過,對于相同的JavaScript加密算法,破解者也可以使用同樣的加解密算法進行反向操作。而且,使用加密算法會增加代碼的體積,降低代碼的執行速度。因此,人們開始思考是否有一種更好的方法確保JavaScript代碼的安全性呢?

          二、JS代碼混淆技術

          JS代碼混淆技術可以將JavaScript代碼轉換成一個新的代碼形式,使其難以理解和破解。這種轉換通常包括將變量名和函數名替換為無意義的字符、刪除代碼中的空白和注釋、將多行代碼壓縮成一行等操作。混淆后的代碼和原代碼在功能上是等效的,但是由于其結構和命名被混淆,甚至看起來無法讀懂。

          例如,下面的函數中,對一段JavaScript代碼進行了簡單的混淆處理:

          Copy codefunction obfuscateCode(code) {
              var lines=code.split("\n");
              var obfuscatedCode="";
              lines.forEach(function(line) {
                  obfuscatedCode +=line
                      .replace(/var /g, "")
                      .replace(/function /g, "")
                      .replace(/return /g, "")
                      .replace(/;/g, "")
                      .replace(/{/g, "")
                      .replace(/}/g, "");
              });
              return obfuscatedCode;
          }
          
          var original_code='function foo(a, b) {var c=a + b;return c;}';
          var obfuscated_code=obfuscateCode(original_code);
          console.log('原始代碼:', original_code);
          console.log('混淆代碼:', obfuscated_code);

          通過混淆技術,原始JavaScript代碼變得更加復雜和難以理解,進而降低了破解的可行性。同時,相比與加密算法,混淆代碼的運行速度和性能也更優秀。

          三、JS解混淆技術

          不過,對于代碼混淆技術,我們同樣可以將其污染(反混淆)。通過分析混淆代碼的結構和操作,我們能夠撰寫出解混淆代碼,進行JavaScript代碼的還原。例如,混淆代碼可能會將許多不同的變量名替換為相同的單個字符,或者將多個行的代碼壓縮到一個代碼行中,可以通過自動化工具或手動方法來反混淆代碼。

          Copy codefunction unobfuscateCode(obfuscatedCode) {
              var unobfuscatedCode=obfuscatedCode
                  .replace(/a /g, "var ")
                  .replace(/b /g, "function ")
                  .replace(/c /g, "return ")
                  .replace(/[0-9]+/g, "")
                  .replace(/=/g, "=")
                  .replace(/\+/g, " + ")
                  .replace(/;/g, ";\n")
                  .replace(/}/g, "\n}\n")
                  .replace(/^\n/, "");
              return unobfuscatedCode;
          }
          
          var obfuscated_code="b foo(a, b){c a + b}"; //從js.jiami.com上獲得的混淆代碼
          var unobfuscated_code=unobfuscateCode(obfuscated_code);
          console.log('混淆代碼:', obfuscated_code);
          console.log('原始代碼:', unobfuscated_code);

          四、JS代碼安全實踐

          如何選擇適當的JS代碼安全實踐方法,取決于應用程序所需的安全級別和安全需求。如果您需要保護代碼內容的安全,可以使用加密算法。如果您的代碼需要長期維護,可以使用代碼混淆技術,使代碼的可讀性降低,這樣也就不容易被別人拿來二次開發和篡改。如果您需要將代碼保持可讀性,但是又需要保護代碼的安全性,可以采取混合應用加密算法和混淆技術相互結合,以最佳的方式實現代碼保護。

          總之,隨著互聯網技術的發展,對于網絡安全的要求越來越高,對于JavaScript的加密和解密,技術發展均取得了一定的進步。但無論是黑客攻擊還是加密解密技術,只是給我們提供了預防的參考方案,絕不能代替不斷加強網站的安全性實踐,并高度喚起安全保護意識。

          jsjiami.com

          如果您對文章內容有不同看法,或者疑問,歡迎到評論區留言,或者私信我都可以。

          也可以到上方網站,底部有我聯系方式詳談。

          碼混淆

          一.基本概念

          java的bytecode很容易通過JAD等反編譯工具還原出源代碼。這樣勢必不滿足安全的定義。如何一定程度上保護需要防止被反編譯的源代碼呢?混淆(obfuscate)技術。注意:用obfuscate防盜版是根本不可能,連匯編這種東西都能被**掉,而java代碼基本上等同于開源的同義詞。用obfuscate只是為了增加反編譯的難度,保護源代碼的知識產權。混淆包照常運行,沒有任何問題??梢允褂梅淳幾g工具如jd-gui查看混淆后的包,驗證混淆效果。

          二.混淆技術

          名稱混淆 name obfuscode

          將有意義的類,字段、方法名稱更改為無意義的字符串。生成的新名稱越 短,字節代碼越小。在名稱混淆的字節代碼中,包,類,字段和方法名稱已重命名,并且永遠不能恢復原始名稱。

          流混淆 Flow Obfuscation

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

          其他

          • 異?;煜?Exception Obfuscation
          • 字符串加密混淆 String Encryption
          • 引用混淆 Reference Obfuscation

          三.常用工具

          1.proguard

          proguard是一個免費的 Java類文件的壓縮,優化,混肴器。它刪除沒有用的類,字段,方法與屬性。使字節碼最大程度地優化,使用簡短且無意義的名字來重命名類、字段和方法
          官網地址:https://www.guardsquare.com/en/products/proguard

          2.yGuard

          yGuard是一款免費的Java混淆器(非開源),它有Java和.NET兩個版本。yGuard 完全免費,基于 Ant 任務運行,提供高可配置的混淆規則。
          官網地址:https://www.yworks.com/products/yguard

          3.allatori

          第二代Java混淆器。所謂第二代混淆器,不僅僅能進行字段混淆,還能實現流混淆。
          命名混淆,流混淆,調試信息混淆,字符串編碼,以及水印技術。對于教育和非商業項目來說這個混淆器是免費的。支持war和jar格式,支持對需要混淆代碼的應用程序添加有效日期。
          官網地址:http://www.allatori.com/

          4.總結

          推薦使用 proguard :開源, 使用簡單 ,文檔豐富完善。

          四.工具對比

          工具

          官網地址

          官方文檔

          開源免費

          名稱混淆

          流混淆

          maven支持

          功能

          proguard

          https://www.guardsquare.com/proguard

          https://www.guardsquare.com/manual/home

          ?


          yGuard

          https://www.yworks.com/products/yguard

          https://yworks.github.io/yGuard/

          ?


          allatori

          https://allatori.com/


          ?(免費用于教育和非商業項目)

          減小包大小;混淆代碼;添加水印

          五.詳細內容

          1.yGuard(https://yworks.github.io/yGuard/)

          • 易于設置:yGuard 是一個 Ant 任務!作為 Ant 任務,yGuard 可以無縫集成到您在 Ant、Maven 和 Gradle 等眾多構建系統中的部署過程中
          • 高級收縮:yGuard 通過依賴分析提供精細的代碼收縮功能。
          • 可配置/安全代碼:yGuard 提供高度可配置的名稱混淆,可保護您的知識產權免受逆向工程。
          • 開源:yGuard 是完全開源的!與昂貴的商業產品相反,yGuard 是并且永遠都是免費的。
          • Java 兼容性:要運行 yGuard 軟件,您需要 JDK 1.7.x 或更高版本以及 Ant 1.5.x 或更高版本(它可能與任一軟件的早期版本兼容,但尚未經過測試)。
            yGuard 與所有已發布的 Java 版本(最高 Java 17)兼容。但是,根據使用的版本,功能可能會略有不同。該文檔包含不同版本支持的功能的詳細說明。如果您打算將 yGuard 與 Java 以外的東西一起使用,還有一個關于3rd 方 JVM 支持的部分。

          ProGuard

          是一個開源的 Java 類文件收縮器、優化器、混淆器和預驗證器。因此,ProGuard 處理的應用程序和庫更小、更快,并且在一定程度上可以抵御逆向工程。

          • 收縮步驟檢測并刪除未使用的類、字段、方法和屬性。
          • 優化器步驟優化字節碼并刪除未使用的指令。
          • 混淆步驟使用簡短無意義的名稱重命名剩余的類、字段和方法。
          • 最后的預驗證步驟將預驗證信息添加到類中,這是 Java Micro Edition 和 Java 6 及更高版本所必需的。

          yGuard

          1.maven引用方式

          <build>
                  <plugins>
                      <plugin>
                          <!--結合ant run 來使用yguard -->
                          <artifactId>maven-antrun-plugin</artifactId>
                          <dependencies>
                              <dependency>
                                  <groupId>com.yworks</groupId>
                                  <artifactId>yguard</artifactId>
                                  <version>3.1.0</version>
                              </dependency>
                          </dependencies>
                          <executions>
                              <execution>
                                  <phase>package</phase>
                                  <goals>
                                      <goal>run</goal>
                                  </goals>
                                  <configuration>
                                      <tasks>
                                          <property refid="maven.compile.classpath" name="mvn.classpath"/>
                                          <!-- <echo message="Using Maven Classpath: ${mvn.classpath}" /> -->
                                          <taskdef name="yguard"
                              classname="com.yworks.yguard.YGuardTask"/>
                                          
                                          <yguard>
                                              <!-- yguard配置 -->
                                          </yguard>
                                          
                                      </tasks>
                                  </configuration>
          
                              </execution>
                          </executions>
                      </plugin>
                  </plugins>
              </build>

          2.yguard配置解析

          寫在前面

          1. yguard共分為兩大任務配置:
            1. rename 混淆名稱 :主要用于修改類名,屬性名,方法名以及參數名等。
            2. shrink 收縮代碼 : 主要用于從多個入口點中刪除所有無法訪問的類、字段和方法。
          1. keep keep是rename和shrink的子元素,用于指定從父級rename或shrink任務中排除的元素。

          注意事項

          1. 注意事項1 :如果項目需要shrink, shrink最好是配置在rename之前。即在進行代碼混淆之前,先進行代碼壓縮。 因為壓縮代碼需要指定壓縮的根代碼。
            舉個例子:比如制定main方法:<method name="void main(java.lang.String[])" class="com.ewa.pipe.dbtransfer.dpl.DplDbtransferApplication" /> 。如果先混淆,DplDbtransferApplication類名被修改的話(比如為A.class),該配置將會無效,所有代碼都會被 shrink 刪除,因為已經找不到DplDbtransferApplication這個類了(類名被修改)。
          2. 其他配置請參考官方文檔。

          配置說明

          基礎配置

           <!-- yguard 是公用配置和rename以及shrink配置的容器標簽 -->
           <yguard>
              <!-- 必須至少指定一個inoutpair元素或一個非空inoutpairs元素才能運行yguard任務。此元素指定輸入和輸出 jar 文件的路徑 
              in out 必須指定設置值,不指定報錯
              1.in 指定一個現有的jar/war文件,其中包含未收縮和未混淆的 .class文件。
              2.out 指定一個 jar/war文件的路徑,該文件將被創建并用于放置收縮和混淆過程的結果。
              3.resources 如何處理資源文件,支持三種值:copy,auto,none。 默認配置copy。
          		    1.copy 直接復制資源文件 默認情況下,只需將所有資源文件復制到輸出 jar 中
          		    2.auto 僅復制那些在壓縮后仍包含一個或多個 .class 文件的目錄中的資源文件。
           		   3.none 丟棄所有資源文件。-->
              <inoutpair 
              in="${project.build.directory}/${project.build.finalName}.${project.packaging}" 
          	out="${project.build.directory}/${project.build.finalName}.${project.packaging}" />     
          	
          	<externalclasses>
          		
          	</externalclasses>
          	
          	<!-- 用于配置一些屬性 ,保存類的調試信息:比如 LineNumberTable:行號表;LocalVariableTable:本地變量表等。  -->
          	<attribute name="SourceFile, LineNumberTable, LocalVariableTable">
            		<patternset>
              		<include name="com.ewa.pipe.**"/>
            		</patternset>	
          	</attribute>
          	
          	<!-- shrink 用于收縮代碼配置。 
          		1.logfile  shrink過程的日志文件
          		2.在shrink過程中,如果有錯誤代碼,代碼將會被替換為: throw new InternalError("Badly shrinked")。
          		比如:當某些類的private屬性被刪除,但是public方法中有引用該屬性,而屬性被刪除了,即會輸出該異常錯誤。
          	-->
          	<shrink logfile="${project.build.directory}/yshrink.log.xml" createStubs="true">
          		<!-- shrink中的keep和rename中的keep一致。 -->
                  <keep>			
                      <method name="void main(java.lang.String[])" class="${mainclass}" />
                  </keep>
              </shrink>
              
              <!-- 用于自定義某些配置和屬性更改。
          	    1.mainclass 用于設置主程序啟動位置,該文件將不會被混淆。
          	    2.logfile 混淆過程中的日志文件保存地址。名稱以“.gz”結尾,yGuard 將自動創建文件的 gzip 壓縮版本,默認為yguardlog.xml
          	    3.conservemanifest 當為false時,重新生成 MANIFEST.MF的內容。默認為false。
          	    4.replaceClassNameStrings  是否混淆代碼中某些字符串跟類名相關的東西。默認為true
          	    比如源碼: System.out.print("com.ewa.pipe.dbtransfer.dpl.mapper.BlendMapper");混淆后: System.out.print("com.ewa.pipe.dbtransfer.dpl.A.B");
          	    5.scramble 是否隨機混淆代碼,默認false。如果為true即每次打包生成的類名將隨機替換。比如Test.class 第一次混淆為A.class,第二次就為B.class
          	    6.annotationClass 某些不必要混淆的數據,比如如下配置為Test注解,當配置到類上時,類中的所有東西不會被混淆;當配置到屬性時,屬性名稱不會被混淆。
          	    -->
              <rename 
                  mainclass="com.ewa.pipe.dbtransfer.dpl.DplDbtransferApplication"
                  logfile="${project.build.directory}/yguard.log.xml"
                  conservemanifest="false"
                  replaceClassNameStrings="true"
                  scramble="false"
                  annotationClass="com.ewa.pipe.dbtransfer.dpl.Test"
              	>   
                  	<!--  -->
                  	<keep>
                      
                  	</keep>	
          		    <!-- 1.error-checking 用于檢測錯誤,檢測到錯誤就失敗停止。 -->
          	       	<property name="error-checking" value="pedantic"/>
          			
          			<!-- 2.error-checking 可用于告訴重命名引擎在混淆期間使用不同的命名方案。目前可以將此屬性設置為以下值之一(默認small,通常使用small就行了):
          			small:將產生非常短的名稱,即生成的 jar 文件將盡可能小。
          			best:會產生很可能被反編譯器和反匯編器誤解的名稱。使用這種命名方案,在大多數文件系統上甚至不可能成功解壓縮或解壓縮生成的 jar 文件(Windows、Standard Unix、Standard Linux、MacOS)。然而,這種方案占用了大量空間,并且生成的 jar 可能會變大(通常大約是兩倍大?。?
          			mix:是其他兩個值的混合,這會導致合理的小但仍然難以反編譯 jar 文件。
          			 -->
          			 <!-- 其他屬性( language-conformity	,overload-enabled,obfuscation-prefix,digests,expose-attributes)請參考官方文檔。 -->
          	       	<property name="naming-scheme" value="small"/>	
              </rename>
           </yguard>

          keep配置說明

          class元素

          class用于在rename和shrink過程中排除某些類,字段和方法。其是keep的子元素。以下是配置說明(- 表示會被收縮,即被刪除 ):

          可見性(是否被收縮)

          public

          protected

          friendly

          private

          none

          -

          -

          -

          -

          public

          *

          -

          -

          -

          protected

          *

          *

          -

          -

          friendly

          *

          *

          *

          -

          private

          *

          *

          *

          *

          屬性說明

          1. name 指定要保留的類名。 在shrink中,只會保留類名稱,類中的屬性和方法都會被刪除掉。
          2. classes 保持類的可見性 :其值是上述:none , public , protected , friendly , private 。默認為none
          3. methods 保留方法的可見性 , 值同classes的描述。默認為none
          4. fields 保留屬性的可見性 , 值同classes的描述。默認為none
          5. extends 保留對繼承了該類的可見性 。1.在shrink中凡是繼承了該類的子類都不會被刪除。 2.在rename中凡是繼承了該類的子類都不會被修改名稱。
          6. implements 保留對實現該接口的可見性 。1.在shrink中凡是實現該接口的類都不會被刪除。 2.在rename中凡是實現該接口的類都不會被修改名稱。

          注意事項

          1. 以上屬性可以單獨使用,一可以混合使用。其 extends/implements 可以和classes, methods,fields混合使用。參考列2說明。

          列1:

              <shrink logfile="${project.build.directory}/yshrink.log.xml">
                 <keep>
                      <!-- 保留NameTest類不被刪除,但是內部的方法和會屬性會被刪除,不論私有還是共有。 -->
                      <class name="com.arm.code.mix.base.NameTest"/>
          			<!-- 保留所有公用的類,方法和屬性。其關聯的類,方法和屬性會被保留,不會被刪除  -->
                 		<class classes="public" methods="public" fields="public"/>
          			<!-- 保留所有繼承了BaseClass的類不被刪除,但是內部的方法和會屬性會被刪除,不論私有還是共有。  -->
          			<class extends="com.arm.code.mix.base.BaseClass"/>
                 </keep>
              </shrink>

          列2:

              <shrink logfile="${project.build.directory}/yshrink.log.xml">
                 <keep>
                      <!-- 保留NameTest類不被刪除,并保留其private級別的方法和屬性 -->
                      <class name="com.arm.code.mix.base.NameTest" methods="private" fields="private"/>
          			<!-- 保留所有繼承了BaseClass的類不被刪除,并保留其private級別的方法和屬性  -->
          			<class extends="com.arm.code.mix.base.BaseClass" methods="private" fields="private"/>
                 </keep>
              </shrink>

          列3:

          一下舉列幾個模式集的列子,模式集可以參考ant。
          
          <!--  include shrink:不需要被刪除的類,保留的類。rename:不需要被混淆的類名 -->
          <class>
            <patternset>
              <include name="com.mycompany.**.*Bean"/>
              <exclude name="com.mycompany.secretpackage.*"/>
              <exclude name="com.mycompany.myapp.SecretBean"/>
          	<!-- 由于 Ant'$'用作轉義字符,因此如果您想將一個作為參數傳遞給任務,則必須使用兩個連續的'$'s( )。'$$'-->
          	<exclude name="org.w3c.sax?.**.*$$*"/> 
            </patternset>
          </class>

          method

          method 用于在rename和shrink過程中排除方法。其是keep的子元素。以下是配置說明(- 表示會被收縮,即被刪除 ):

          <!-- 這將保留MyClass類的main和foo方法。此外,所有readObject和writeObject方法(用于序列化)都將保存在com.mycompany.myapp.data包的所有類中。
          	請注意,您必須指定返回參數的類型,即使它是 void,并且您必須為所有類使用完全限定名稱,即使是java.lang package. -->
          <method class="com.mycompany.myapp.MyClass"
            name="void main(java.lang.String[])"/>
          <method class="com.mycompany.myapp.MyClass"
            name="int foo(double[][], java.lang.Object)"/>
          <method name="void writeObject(java.io.ObjectOutputStream)">
            <patternset>
              <include name="com.mycompany.myapp.data.*"/>
            </patternset>
          </method>
          <method name="void readObject(java.io.ObjectInputStream)">
            <patternset>
              <include name="com.mycompany.myapp.data.*"/>
            </patternset>
          </method>

          field

          field 您可以按名稱指定應從收縮或名稱混淆中要保留的字段

          <!-- 保留MyClass類中的所有字段。
          	此外,所有serialVersionUID字段(用于序列化)都將保存在com.mycompany.myapp.data包的所有類中。 -->
          <field class="com.mycompany.myapp.MyClass" name="field"/>
          <field name="serialVersionUID">
            <patternset>
              <include name="com.mycompany.myapp.data.*"/>
            </patternset>
          </field>

          package

          package 用于從重命名過程中排除某些包的名稱。它不能用于收縮(shrink)過程 。這對類、方法或字段名稱沒有影響。

              <package>
                <patternset>
          		<!-- com.mycompany.myapp不被混淆。myapp下的包名還是會被混淆 -->
                  <include name="com.mycompany.myapp.*"/>
          		<!-- com.mycompany.myapp不被混淆。myapp下的包名也不會被混淆 -->
          		<include name="com.mycompany.myapp.**"/>
                </patternset>
              </package>

          3.幾種情況下的使用方式

          springboot項目

          1.注意事項

          1. yguard插件執行要放在 spring boot打包項目之前,因為反置的話,會造成jar中的springboot的啟動相關類被混淆,而造成啟動項目失敗。

          2.項目使用失敗的問題收集總結

          1. 本地打包之后啟動項目失?。河捎谑潜镜豬dea將jdk設置成jdk17了,導致打包失敗。 設置為jdk8后成功啟動。
          2. 項目使用mybaties plus,項目里只有一個接口:public interface TimePullLogMapper extends BaseMapper<TimePullLog>{} , 造成混淆后打包報錯:spring至少一個bean實現。后面加上:<class implements="com.arm.boot.core.base.BaseMapper"/> 后正常。==
          3. service的接口和實現都要暴露,不然spring的注入和nacos的服務發現都會存在問題。

          3.配置模版

          <keep>
                                                      <!--包名不混淆配置-->
                                                      <package>
                                                          <patternset>
                                                              <include name="com.arm.oceansearch.**"/>
                                                          </patternset>
                                                      </package>
                                                      <!--mybaites 相關的mapper混淆后,會造成boot項目啟動失敗 -->
                                                      <class implements="com.arm.boot.core.base.BaseMapper"/>
                                                      <!--mybaites默認生成sql時是使用的實體類的類名,所以不能混淆-->
                                                      <class implements="com.arm.oceansearch.entity.BaseEntity"/>
                                                      <!-- 本包的controller混淆后,無法讀取mapping映射,原因未知。-->
                                                      <class>
                                                          <patternset>
                                                              <include name="com.arm.oceansearch.controller.*"/>
                                                          </patternset>
                                                      </class>
                                                      <!-- service的接口和實現都要暴露,不然spring的注入和nacos的服務發現都會存在問題。 -->
                                                      <class>
                                                          <patternset>
                                                              <include name="com.arm.oceansearch.service.**"/>
                                                          </patternset>
                                                      </class>
                                                      <!--main方法配置-->
                                                      <method name="void main(java.lang.String[])"
                                                              class="com.arm.oceansearch.OceanSearchApplication"/>
                                                  </keep>


          簡介

          ProGuard 是一個開源的 Java 類文件收縮器、優化器、混淆器和預驗證器。因此,ProGuard 處理的應用程序和庫更小、更快,并且在一定程度上可以抵御逆向工程。

          • 收縮步驟檢測并刪除未使用的類、字段、方法和屬性。
          • 優化器步驟優化字節碼并刪除未使用的指令。
          • 混淆步驟使用簡短無意義的名稱重命名剩余的類、字段和方法。
          • 最后的預驗證步驟將預驗證信息添加到類中,這是 Java Micro Edition 和 Java 6 及更高版本所必需的。

          對反射的處理

          反射和內省對于任何代碼的自動處理都存在特殊的問題。在 ProGuard 中,代碼中動態創建或調用(即按名稱)的類或類成員也必須指定為入口點。例如,Class.forName()構造可以在運行時引用任何類。通常不可能計算必須保留哪些類(使用它們的原始名稱),因為類名可能是從配置文件中讀取的,例如。因此,您必須在 ProGuard 配置中指定它們,同樣簡單-keep選項

          • Class.forName("SomeClass")
          • SomeClass.class
          • SomeClass.class.getField("someField")
          • SomeClass.class.getDeclaredField("someField")
          • SomeClass.class.getMethod("someMethod", null)
          • SomeClass.class.getMethod("someMethod", new Class[] { A.class,... })
          • SomeClass.class.getDeclaredMethod("someMethod", null)
          • SomeClass.class.getDeclaredMethod("someMethod", new Class[] { A.class,... })
          • AtomicIntegerFieldUpdater.newUpdater(SomeClass.class, "someField")
          • AtomicLongFieldUpdater.newUpdater(SomeClass.class, "someField")
          • AtomicReferenceFieldUpdater.newUpdater(SomeClass.class, SomeType.class, "someField")

          支持

          1. 可單獨使用。首先,下載一個ProGuard 版本或者構建 ProGuard從源頭。然后可以通過調用目錄中的腳本直接從命令行執行 ProGuard bin:
            linux/mac:bin/proguard.sh -injars path/to/my-application.jar \ -outjars path/to/obfuscated-application.jar \ -libraryjars path/to/java/home/lib/rt.jar
            windows:bin\proguard.bat -injars path/to/my-applicati^ -outjars path/to/obfuscated-application.jar ^ -libraryjars path/to/java/home/lib/rt.jar
          2. Gradle 模式
          3. ant模式
          4. Maven模式:(沒有正式提供 maven 集成,也無法提供支持,但有可用的解決方案,但 Guardsquare 不保證它們提供的功能。)來源實現:
            https://github.com/wvengen/proguard-maven-plugin
            https://github.com/dingxin/proguard-maven-plugin

          錯誤解析

          1. [proguard] Error: The input doesn't contain any classes. Did you specify the proper '-injars' options?
          處理:<inFilter>com/ewa/pipe/**</inFilter>, inFilter標簽設置為包路徑地址,把‘.’換成‘/’。
          
          injar : 指定target中的一個目標地址:這里指定編譯后的 classes文件夾。  inFilter 指定的是 classes的內部的文件夾(package)地址。
          <!-- 加載文件的過濾器,就是你的工程目錄了-->
                              <inFilter>com/arm/code/**</inFilter>
                              <!-- 對什么東西進行加載,這里僅有classes成功,畢竟你也不可能對配置文件及JSP混淆吧-->
                              <injar>classes</injar>

          以下是一個例子說明,如果你想更多的有用信息,請查看文檔(https://www.guardsquare.com/manual/configuration/usage)


          主站蜘蛛池模板: 精品无码一区在线观看| 亚洲av乱码一区二区三区按摩| 日韩AV无码一区二区三区不卡| 亚洲线精品一区二区三区影音先锋| 国产在线第一区二区三区| 久久国产免费一区二区三区 | 91久久精品午夜一区二区| 亚洲成AV人片一区二区密柚| 国产成人精品a视频一区| 无码精品蜜桃一区二区三区WW| 国模极品一区二区三区| 国产精品无码一区二区三区毛片| 国产91久久精品一区二区| 成人无码精品一区二区三区| 日本免费电影一区| 少妇无码AV无码一区| 中文字幕亚洲综合精品一区| 欧美激情国产精品视频一区二区 | 水蜜桃av无码一区二区| 中文字幕精品一区二区精品| 亚洲一区综合在线播放| 国产成人精品一区二三区熟女| 精品乱码一区内射人妻无码| 亚洲色精品vr一区二区三区| 麻豆一区二区免费播放网站| 国产一区二区三区91| 亚洲av乱码一区二区三区| 91在线视频一区| 一区二区视频传媒有限公司| 日韩在线观看一区二区三区| 精品熟人妻一区二区三区四区不卡| 在线免费一区二区| 老熟妇仑乱视频一区二区| 加勒比精品久久一区二区三区| 91久久精品午夜一区二区| 无码AⅤ精品一区二区三区| 色窝窝免费一区二区三区 | 亚洲国产美女福利直播秀一区二区| 日韩美一区二区三区| 蜜桃AV抽搐高潮一区二区| 亚洲一区二区三区丝袜|