1 JAVAScript 簡介
JavaScript 壓縮、混淆和加密技術
對于網頁來說,其邏輯是依賴于JavaScript來實現的,JavaScript 有如下特點:
- JavaScript 代碼運行于客戶端,也就是它必須要在用戶瀏覽器端加載并運行。
- JavaScript 代碼是公開透明的,也就是說瀏覽器可以直接獲取到正在運行的 JavaScript 的源碼。
壓縮、混淆、加密技術:
- 代碼壓縮:即去除JavaScript 代碼中的不必要的空格、換行等內容,使源碼都壓縮為幾行內容,降低代碼可讀性,當然同時也能提高網站的加載速度。
- 代碼混淆:使用變量替換、字符串陣列化、控制流平坦化、多態變異、僵尸函數、調試保護等手段,使代碼變得難以閱讀和分析,達到最終保護的目的。但這不影響代碼原有功能。是理想、實用的JavaScript保護方案
- 代碼加密:可以通過某種手段將 JavaScript 代碼進行加密,轉成人無法閱讀或者解析的代碼,如將代碼完全抽象化加密,如 eval 加密。另外還有更強大的加密技術,可以直接將 JavaScript 代碼用 C/C++ 實現,JavaScript 調用其編譯后形成的文件來執行相應的功能,如Emscripten 還有 WebAssembly。
2 OB混淆
OB 混淆全稱 Obfuscator,Obfuscator 其實就是混淆的意思。
官網:https://obfuscator.io/ ,其作者是一位叫 Timofey Kachalov 的俄羅斯JavaScript開發工程師,早在 2016 年就發布了第一個版本。
2.1 OB 混淆具有以下特征:
1、一般由一個大數組或者含有大數組的函數、一個自執行函數、解密函數和加密后的函數四部分組成;
2、函數名和變量名通常以 _0x 或者 0x 開頭,后接 1~6 位數字或字母組合;
3、自執行函數,進行移位操作,有明顯的 push、shift 關鍵字;
例如在下面的例子中,_0x3f26() 方法就定義了一個大數組,自執行函數里有 push、shift 關鍵字,主要是對大數組進行移位操作,_0x1fe9() 就是解密函數,hi() 就是加密后的函數。
2.2 OB混淆介紹
JavaScript 混淆完全是在 JavaScript 上面進行的處理,它的目的就是使得 JavaScript 變得難以閱讀和分析,大大降低代碼可讀性,是一種很實用的 JavaScript 保護方案。
JavaScript 混淆技術主要有以下幾種:
- 變量混淆: 將帶有含意的變量名、方法名、常量名隨機變為無意義的類亂碼字符串,降低代碼可讀性,如轉成單個字符或十六進制字符串。
- 字符串混淆: 將字符串陣列化集中放置、并可進行 MD5 或 Base64 加密存儲,使代碼中不出現明文字符串,這樣可以避免使用全局搜索字符串的方式定位到入口點。
- 屬性加密: 針對 JavaScript 對象的屬性進行加密轉化,隱藏代碼之間的調用關系。
- 控制流平坦化: 打亂函數原有代碼執行流程及函數調用關系,使代碼邏變得混亂無序。
- 僵尸代碼: 隨機在代碼中插入無用的僵尸代碼、僵尸函數,進一步使代碼混亂。
- 調試保護: 基于調試器特性,對當前運行環境進行檢驗,加入一些強制調試 debugger 語句,使其在調試模式下難以順利執行 JavaScript 代碼。
- 多態變異: 使 JavaScript 代碼每次被調用時,將代碼自身即立刻自動發生變異,變化為與之前完全不同的代碼,即功能完全不變,只是代碼形式變異,以此杜絕代碼被動態分析調試。
- 鎖定域名: 使 JavaScript 代碼只能在指定域名下執行。
- 反格式化: 如果對 JavaScript 代碼進行格式化,則無法執行,導致瀏覽器假死。
- 特殊編碼: 將 JavaScript 完全編碼為人不可讀的代碼,如表情符號、特殊表示內容等等。
總之,以上方案都是 JavaScript 混淆的實現方式,可以在不同程度上保護 JavaScript 代碼。
2.3 OB混淆JS
新建一個文件夾,隨后進入該文件夾,初始化工作空間
npm init
提示我們輸入一些信息,創建一個 package.json 文件,這就完成了項目初始化了。
接下來我們來安裝 javascript-obfuscator這個庫:
npm install javascript-obfuscator --save
2.3.1 代碼壓縮
這里javascript-obfuscator也提供了代碼壓縮的功能,使用其參數 compact即可完成JavaScript 代碼的壓縮,輸出為一行內容。默認是 true,如果定義為 false,則混淆后的代碼會分行顯示。
var code = `
let x = '1' + 1
console.log('x', x)
`
const options = {
compact: true, // 代碼壓縮配置
}
const obfuscator = require('javascript-obfuscator')
function obfuscate(code, options) {
return obfuscator.obfuscate(code, options).getObfuscatedCode()
}
console.log(obfuscate(code, options))
2.3.2 變量名混淆
變量名混淆可以通過配置identifierNamesGenerator 參數實現,我們通過這個參數可以控制變量名混淆的方式,如hexadecimal則會替換為 16 進制形式的字符串,在這里我們可以設定如下值:
- hexadecimal:將變量名替換為 16 進制形式的字符串,如 0xabc123。
- mangled:將變量名替換為普通的簡寫字符,如 a、b、c 等。 該參數默認為hexadecimal。
我們將該參數修改為 mangled 來試一下:
const code = `
let hello = '1' + 1
console.log('hello', hello)
`
const options = {
compact: true,
identifierNamesGenerator: 'mangled'
}
2.3.3 字符串混淆
字符串混淆,即將一個字符串聲明放到一個數組里面,使之無法被直接搜索到。我們可以通過控制 stringArray 參數來控制,默認為 true。
const code = `
var a = 'hello world'
`;
const options = {
compact: false,
unicodeEscapeSequence: true //對字符串進行 Unicode 轉碼
};
JavaScript混淆知識點,今天就暫時先介紹到這里。這些知識不論對前端開發人員還是爬蟲技術人員都會有所收獲,有所感悟。只有了解清楚它的原理,才能更好的使用、開發乃至攻防。有問題歡迎在評論區留言,也可以動動小手點點贊!