Electron加密與安全
引言
目前網絡上主要流傳的加密就只是網頁文件打包成asar
和JS混淆加密,以及用addon的方式,這幾種方式的話,基本就沒有什麼破解難度。針對的官方asar
的打包,這種方式就僅僅是將衆多的文件以原文的形式放在一個文件中,不存在任何的加密手段;JS混淆加密這種方式仍然是可以通過看代碼的方式來分析出原本的邏輯;addon的方式只要找到調用的接口那麼很容易就會被幹掉。我們這裏討論的話題當然也是和以上的幾種方式有關,不過更深入的就是,我們在這種基礎之上作出更多的保護措施。
本篇只討論加密和安全的細節,不涉及到具體的源碼和實現。因爲這些東西已經應用到了項目中,不能直接放出來也不能說的太清楚,不過詳細的思路我會說清楚,有興趣的同學可以藉助這個思路繼續深入;且因個人水平有限,還有很多的方向沒有顧及,歡迎我們一起討論。
QQ羣: 931238114(羣名爲:ReactOS學習交流)
目的
本篇討論的核心主題是重新編譯Electron,在Electron裏面加入JS的解密代碼的思路;網上已經有大佬在很久之前討論過這個話題的(參考:https://www.v2ex.com/t/493344,https://www.jishuwen.com/d/2AI3/zh-hk)。我們這裏的思路要比這個帖子裏面的思路要深入一些,這個帖子裏面說的方式是C++和node.js端都寫解密函數的方式。
這個方式有一個缺陷就是,nodejs
的解密代碼沒辦法得到安全保證。雖然磁盤上的文件加密了,但是如果通過瀏覽被編譯在electron.exe裏面的nodejs
代碼,那麼這個方式會直接崩掉。我們的目的肯定不是說讓我們的程序不可被破解,而是儘可能增加破解的門檻和難度。
思路
Electron的源碼加密和安全是多方面的,不僅僅是隻加密源碼這一塊,還牽涉到加密之後阻止查看源碼的部分。因此這裏主要就分成兩部分加密和安全。
加密部分
我們現在都知道electron的源碼是沒有加密的,electron在保護源碼的路上做的就只是將文件打包成asar
,而且還在electron的nodejs
端寫了大量的重載一類的東西來支持這個asar
,那麼很顯然我們並不能繞過asar
這個環節,我們最好的方式就是我們自己對asar
的內容進行加密,然後在Electron中進行文件解密操作。
文件加密思路:
- 選擇對稱加密算法,方便解密時文件內容對齊
- 在生成
asar
時,在文件頭時不做處理,在寫入實際文件內容時進行加密
EXE解密思路:
-
EXE中存在三個地方對ASAR的進行讀取,分別是:
- 通用
asar
讀取類 asar
JOB類- node 端讀取類
針對以上三處進行解密了之後,就已基本上已經處理完了所有的讀取文件的方式,包含
js
端對asar
的讀取;\ - 通用
加密方式選擇:
推薦AES對部分文件進行加密,只需要對重要的文件進行加密即刻;大範圍的加密雖然提升了安全性,但是程序的性能會嚴重下降。
安全部分
加密部分完成以後,那麼就需要考慮如何提高破解的成本問題了。Electron程序需要分成三個部分來進行處理,分別如下:
- Electron進程本身
- Node Inspector
- DEV Tools
Electron進程本身安全處理
- 使用VMP對解密代碼進行VM保護
- 使用VM對程序本身進行VM
- 不使用第三方解密算法,例如,不使用OpenSSL庫進行解密,推薦直接嵌入一個解密算法;
禁用Node的Inspector
Node的Inspector可以直接調試node進程的源碼,使用VSCode
進行主進程調試的時候就是使用的這個模式,如果哪怕已經對文件加密了,那麼仍然可以通過VSCode
調試查看到JS源碼,所以需要從根源上禁止啓動Inspector
.在NODE.js裏面禁用Inspector意義不大,因爲斷點可以斷在你的判斷代碼之前。哪怕修改node.js的創建代碼也沒有意義,因爲node.js的代碼是直接編譯進進程本身的,除非同樣也加密,然後再取出。不過相對更麻煩。
- 通過參數的形式判斷是否需要啓動
inspector
,判斷參數的代碼也用VMP進行保護; - 物理閹割inspector, 修改
toolchain.ninja
,或者修改electron_node.ninja
直接,或者直接修改源碼的方式將inspector砍掉,這樣誰都不用調試了。只是相對編譯麻煩;
禁用DevTools
禁用DevTools
的代碼爲了防止有人修改未加密代碼強行開啓開發者工具的。
- 移除
devtools.pak
, 一般情況下,devtools.pak
在resources.pak
中,可以通過修改toolchain.ninja
,在編譯resources.pak
時移除devtools.pak
; - 監聽
devtools
窗口的創建和啓動,(爲了防止第一步中破解者直接通過換一個resources.pak
就讓DevTools
重載的問題),監聽devtools-opened
事件,參考鏈接:https://www.gznotes.com/how-to-protect-electron-app-source-code/ - 在主進程中檢查
resources.pak
的校驗值,防止文件被替換。
技能要求
- 能寫C++程序(用於寫加密代碼)
- 加密算法,解密算法(推薦使用AES進行加解密,速度很快)
- 編譯和修改Electron源碼(用於引入加密函數)
- 編寫解密函數
- 禁用Inspector
- 檢查非法啓動參數
- 能寫NODE.js或者JS
- 用於修改electron的JS端,使其適應Electron的加密;
- 修改官方的
asar
打解包工具,使其在打包時,將加密之後的數據寫入到asar
文件中;
Electron版本選擇的話,我個人建議最好從4.0開始,因爲4.0開始的版本採用的是gn
的方式,配置比之前的簡單,而且編譯的速度要比這之前的快。國內下載Chromium源碼比較困難,折騰幾天搞不定都是正常的。
Electron編譯選項開關
使用以下配置或參數,可以極大減小electron的文件體積, 32位4.2.9版本的electron,從76.1M到62M左右
1. gn args:
is_debug = false
target_cpu = "x86"
enable_nacl = false
is_component_build = false
is_component_ffmpeg=false
symbol_level = 2
blink_symbol_level=2
enable_basic_printing = false
enable_resource_whitelist_generation=false
debug_devtools = false
#enable_plugins = false
enable_pdf = false
enable_webrtc = false
enable_plugin_installation =false
enable_spellcheck = false
use_browser_spellchecker = false
enable_print_preview = false
enable_web_speech = false
#enable_extensions = false // used by electron.
#enable_electron_extensions = false
enable_task_manager = false
enable_themes = false
win_pdf_metafile_for_printing = false
enable_service_discovery = false
enable_wifi_bootstrapping = false
enable_webvr = false
enable_notifications = false
disable_ftp_support = true
#enable_electron_extensions = false
enable_fake_location_provider = false
enable_message_center = false
enable_nacl_nonsfi = false
enable_native_notifications = false
enable_one_click_signin = false
#enable_openvr = false
enable_session_service = false
enable_tts = false
enable_vr = false
enable_windows_mr = false
#pdf_is_standalone = true
pdf_use_skia_paths = false
pdf_use_skia = false
pdf_is_complete_lib = false
pdf_enable_xfa_tiff = false
pdf_enable_xfa_png = false
pdf_enable_xfa_gif = false
pdf_enable_xfa_bmp = false
pdf_enable_xfa = false
pdf_enable_v8 = false
pdf_enable_click_logging = false
pdf_bundle_freetype = false
rtc_build_examples = false
rtc_build_tools = false
#toolkit_views = false
treat_warnings_as_errors = false
start_daemons_for_testing = false
is_unsafe_developer_build = true
angle_enable_custom_vulkan_cmd_buffers=false
angle_enable_d3d11=true
angle_enable_d3d9=true
angle_enable_vulkan=false
angle_enable_gl=false
angle_enable_gl_null=false
angle_enable_essl=false
3.1 replace `/Oy- ` = ` ` (use grepWin)
replace `/GS ` = ` ` (use grepWin)
3.2 Set from `/O2 ` to `/Ox /Os /GS- /GF /GR- /Oy `.(use grepWin)
3.3 Set from `/O1 ` to `/Ox /Os /GS- /GF /GR- /Oy `.(use grepWin)
5. Disable dynamic address for electron.exe
link flag :
1. change fixed address from `/FIXED$:NO` to `/FIXED`.
2. change dynamic address from `/DYNAMICBASE` to `/DYNAMICBASE$:NO`
參考鏈接
附上一些實用鏈接:
GN-Build Instructions: https://github.com/electron/electron/blob/master/docs/development/build-instructions-gn.md
減少Electron體積的:https://zhuanlan.zhihu.com/p/64070741
GN編譯配置 :https://blog.csdn.net/Vincent95/article/details/78477597
windows electron-4.0.5編譯指南:https://blog.csdn.net/bjrxyz/article/details/90347292