跳至主要內容
KOH NEWS 今日成報

Android代碼加固技術文整理:以AES-256-GCM加密隱藏DEX的完整流程

科技 深度報導

掘金技術文章整理Android敏感代碼加密流程:AES-256-GCM加密DEX、HDX1密文頭設計與d8構建流水線的可核實細節。

2026年9月24日,開發者陳柒吖在中國大陸技術社羣掘金發布文章《安卓代碼加固(1):加密DEX》,記錄一套在Android應用內加密敏感代碼的工程做法。該文屬系列第一篇,本臺依據文章可核實內容,整理其技術方案輪廓。

目標與整體設計

作者開宗明義指出,此方案的目的是實現Android敏感代碼加密,核心原則是業務實作不進入主DEX。具體路徑為:先將業務代碼編譯為jar,再以d8工具的release模式打成classes.dex,最後用AES-256-GCM演算法加密,產出檔案寫入assets/payload/hidden.dex.enc。

值得注意的是接入方式。作者強調,接入方不用執行這條流水線;更換實作時,只需在SDK倉庫重新組裝,把新的AAR交給宿主應用即可。也就是說,加密流程完全收攏在SDK這一側,宿主僅消費密文。

密文格式:HDX1頭部的設計

文章給出了密文位元組流的固定布局。Java加密器寫死四組常量:魔數HDX1(4位元組)、nonce長度12位元組、GCM標籤128位元、金鑰長度32位元組。最終檔案結構為:

HDX1 (4) || nonce (12) || ciphertext + tag (16)

HDX1頭部同時承擔自檢功能。Gradle與檢查腳本以檔案頭判斷這是否為加密payload:明文dex的檔案頭是dex三個字母。作者提醒,若打包後的APK內仍能搜到以dex開頭的hidden檔案,代表加密環節沒有被執行。

Nonce的處理也有明確規範。每次打包時,nonce由SecureRandom重新生成並寫入密文頭,不隨金鑰一起分發。同一份源碼打包兩次,密文位元組流也會不同。

構建流水線的四個步驟

依文章描述,流水線依序為四段:

第一,編譯landing-page jar。hidden-sdk模組依賴hidden-landing-page的bundleLibRuntimeToJar任務,取得實作類。

第二,以d8打release dex。腳本呼叫最新build-tools中的d8,以android.jar與SDK jar作為—lib參數。這些函式庫類不會被打進加密dex,—lib僅提供classpath符號,例如KeepAlive等參照。實作類也不再實作已刪除的HiddenApi介面。腳本中另有一道防呆檢查:若產出檔案前三位元組不是dex,直接以非零狀態終止。

第三,AES-GCM加密。以javac編譯PayloadEncryptor.java,金鑰HIDDEN_PAYLOAD_KEY透過子程序環境變數傳入,寫出hidden.dex.enc。加密時先產生12位元組nonce,演算法指定為AES/GCM/NoPadding;Java的doFinal會自動把16位元組tag接在密文之後,寫檔時無須再單獨追加。

第四,放入SDK assets。sourceSets將generated/encrypted_assets//payload目錄分別指定給debug與release變體,隨後一併打入AAR。

技術脈絡

DEX加密是Android代碼加固的常見手段之一,目的在於對抗逆向工程,避免商業邏輯被反編譯工具直接讀取。該文採用的組合,d8脫離Gradle單獨執行、AES-256-GCM對稱加密、隨機nonce寫入密文頭,均屬可由公開文件查證的標準做法;文中未涉及運行時解密與so層還原的細節,作者註明該部分屬系列後續內容,原文亦指向文末連結的完整版博文。

本臺僅整理文章披露的技術事實,未對該方案的安全性做出評估。金鑰如何分發、native層如何持有金鑰等關鍵環節,原文此篇未完整交代,相關結論有待後續篇章驗證。

主題

科技與平台

回到即時新聞