【HarmonyOS Next】鴻蒙加固方案調研和分析
一、前言
根據鴻蒙應用的上架流程,本地構建app文件后,上架到AGC平臺,平臺會進行解析。根據鴻蒙系統的特殊設置,仿照IOS的生態閉環方案。只能從AGC應用市場下載app進行安裝。這樣的流程一定程度上提高了防破解和逆向的成本。
但應用代碼防逆向是一個持續攻防對抗的過程,如對代碼文件保護有更高的要求,需要結合其他安全加固措施,進一步提高逆向分析應用的難度。
二、目前市面上鴻蒙的加固服務商:
1.梆梆加固
https://www.bangcle.com/pages/cat_id/96.html
2.NAGA 娜迦科技
https://www.nagain.com/activity/article/76/#/produCtenter/securityReinforce/hap
娜迦移動應用APP安全加固服務
https://developer.huawei.com/consumer/cn/market/prod-detail/6b8d4d7cebf743aaa9d926fe55658a01/1
3.網易易盾
https://dun.163.com/product/harmony-reinforce
4.愛加密
https://www.ijiami.cn/harmonyOS
5.FairGuard 游戲加固
https://www.fair-guard.com/help/list-375.html
6. 360加固
https://jiagu.360.cn/#/global/details/HongMengNext
三、鴻蒙加固方案
1.代碼混淆
對 ArkTS 代碼中的類名、方法名、變量名等進行替換,使用無意義的字符來代替原本有明確含義的名稱。攻擊者難以從代碼符號中獲取有價值的信息,增加了代碼理解和逆向分析的難度。
- 控制流混淆:通過改變代碼的執行流程,在不影響程序正常功能的前提下,插入一些無用的跳轉、循環和條件判斷語句。這樣會打亂代碼的邏輯結構,使得逆向工程中難以還原出清晰的程序邏輯。
加密保護
entry/build-profile.json5
"enable": true,即可開啟混淆。// 打包
將項目配置為release模式進行打包,此時混淆才會實際執行,最終生成混淆后的應用包。
另外,如果想混淆字符串字面量屬性名,還需在上述基礎上再使用-enable-string-property-obfuscation
2.代碼加密:
對 ArkTS 源代碼或編譯后的字節碼進行加密處理,在應用運行時動態解密。即使攻擊者獲取到應用文件,看到的也是加密后的代碼,無法直接進行分析和篡改。
- 資源加密:對應用中的圖片、音頻、視頻等資源文件進行加密,防止資源被非法提取和復用。應用在運行時會自動對加密資源進行解密和加載。
可以編寫腳本對代碼文件進行加密處理,在應用啟動時再進行解密。常見的加密算法有 AES(高級加密標準)。也可使用一章節中的三方服務商。
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import osdef encrypt_file(key, input_file_path, output_file_path):cipher = AES.new(key, AES.MODE_CBC)with open(input_file_path, 'rb') as f_in:plaintext = f_in.read()ciphertext = cipher.encrypt(pad(plaintext, AES.block_size))with open(output_file_path, 'wb') as f_out:f_out.write(cipher.iv)f_out.write(ciphertext)# 使用示例
key = os.urandom(16) # 生成 16 字節的密鑰
input_file = 'your_code_file.js'
output_file = 'encrypted_code_file.js'
encrypt_file(key, input_file, output_file)
也可使用AGC平臺提供的加密,不過會對APP冷啟動帶來時間影響。目前加密還是白名單設置,并非開放給所有APP。
3.虛擬機加殼:
將應用程序包裹在一個自定義的虛擬機環境中運行,對應用的指令集進行轉換和解釋執行。攻擊者需要先破解虛擬機的運行機制,才能進一步分析應用代碼,增加了逆向的難度。
- 代碼抽取加殼:將應用的核心代碼從原程序中抽取出來,存儲在加殼程序的特定區域,并在運行時動態加載和執行。這樣可以有效保護核心代碼不被輕易獲取和分析。
運行時防護
4.反調試檢測:
在應用運行過程中,實時檢測是否有調試器連接。如果檢測到調試行為,應用可以采取相應的措施,如終止運行、彈出警告提示或進行數據加密等,防止攻擊者通過調試手段獲取應用的敏感信息。【這些檢測方法并非絕對安全,有經驗的攻擊者可能會繞過這些檢測。】
在 ArkTS 中,要判斷是否運行在模擬器環境,可通過讀取系統文件信息來實現:
import fileio from '@ohos.fileio';// 判斷是否運行在模擬器環境的函數
async function isRunningOnEmulator(): Promise<boolean> {const sysDirPath = '/sys/devices/virtual/dmi/id';const biosVendorFilePath = `${sysDirPath}/bios_vendor`;try {// 檢查 sysDirPath 是否存在const sysDirStat = await fileio.stat(sysDirPath);if (sysDirStat) {// 檢查 biosVendorFilePath 是否存在const biosVendorFileStat = await fileio.stat(biosVendorFilePath);if (biosVendorFileStat) {// 讀取 bios_vendor 文件內容const fd = await fileio.open(biosVendorFilePath, 0o400);const buffer = new ArrayBuffer(1024);const readLength = await fileio.read(fd, buffer);const biosVendor = new TextDecoder().decode(buffer.slice(0, readLength));await fileio.close(fd);// 判斷是否包含模擬器相關標識return biosVendor.includes('Android') || biosVendor.includes('Genymotion');}}} catch (e) {console.error(`Error checking emulator: ${e.message}`);}return false;
}// 使用示例
isRunningOnEmulator().then((result) => {if (result) {console.log('The app is running on an emulator.');} else {console.log('The app is running on a real device.');}
});
5.內存保護:對應用在內存中的數據和代碼進行監控和保護,防止內存被非法訪問、篡改或注入惡意代碼。可以采用內存加密、內存訪問控制等技術手段來實現內存保護。
- 設備環境檢測:檢測應用運行的設備環境是否安全,如是否存在模擬器、Root / 越獄設備等。如果檢測到不安全的設備環境,應用可以限制部分功能或拒絕運行,降低被攻擊的風險。
數據安全防護
處理敏感數據并及時清除示例:
SensitiveDataProtectionExample {private sensitiveData: string | null = null;handleSensitiveData() {// 模擬獲取敏感數據this.sensitiveData = 'mySecretPassword';// 處理敏感數據console.log(`Processing sensitive data: ${this.sensitiveData}`);// 處理完后及時清除敏感數據this.sensitiveData = null;}build() {Column({ space: 50 }) {Button('Process Sensitive Data').onClick(() => {this.handleSensitiveData();})}.width('100%')}
}
struct
6.數據傳輸加密:在應用與服務器之間進行數據傳輸時,采用 SSL/TLS 等加密協議對數據進行加密,防止數據在傳輸過程中被竊取或篡改。
- 數據存儲加密:對應用在本地存儲的敏感數據,如用戶信息、配置文件等,進行加密處理。只有在經過授權的情況下才能解密和訪問這些數據,確保數據的安全性。