1. 程式人生 > >代孕_深圳代孕費用多少

代孕_深圳代孕費用多少

代孕_深圳代孕費用多少█【微信:138-0226-9370】100%包成功██ivf2008.com█ █ 代孕包成功,代孕包男孩,供卵代孕,十年老品牌代孕公司

使用js的混淆加密,其目的是為了保護我們的前端程式碼邏輯,對應一些搞技術吃飯的公司來說,為了防止被競爭對手抓取或使用自己的程式碼,就會考慮如何加密,或者混淆js來達到程式碼保護。

 

1、為什麼需要js混淆

在web系統發展早期,js在web系統中承擔的職責並不多,只是簡單的提交表單,js檔案非常簡單,也不需要任何的保護。

隨著js檔案體積的增大,為了縮小js體積,加快http傳輸速度,開始出現了很多對js的壓縮工具,比如 uglify、compressor、clouser。。。它們的工作主要是

    · 合併多個js檔案

    · 去除js程式碼裡面的空格和換行

    · 壓縮js裡面的變數名

    · 剔除掉註釋

壓縮後的程式碼

 

雖然壓縮工具出發點都是為了減少js檔案的體積,但是人們發現壓縮替換後的程式碼已經比原始碼可讀性差了很多,間接起到了程式碼保護的作用,於是壓縮js檔案成為了前端釋出的標配之一。但是後來市面上主流瀏覽器chrome、Firefox等都提供了js格式化的功能,能夠很快的把壓縮後的js美化,再加上現代瀏覽器強大的debug功能,單純壓縮過的js程式碼對於真正懷有惡意的人,已經不能起到很好的防禦工作,出現了"防君子不防小人"的尷尬局面。

 

chrome開發者工具格式化之後的程式碼

 

而在web應用越來越豐富的今天,伴隨著瀏覽器效能和網速的提高,js承載了更多的工作,不少後端邏輯都在向前端轉移,與此同時也讓更多的不法分子有機可乘。在web模型中,js往往是不法分子的第一個突破口。知曉了前端邏輯,不法分子可以模擬成一個正常的使用者來實施自己的惡意行為。所以,在很多登入、註冊、支付、交易等等頁面中,關鍵業務和風控系統依賴的js都不希望被人輕易的破解,js混淆應運而生。

 

2、js混淆是不是紙老虎

 

這是一個老生常談的問題。實際上,程式碼混淆早就不是一個新鮮的名詞,在桌面軟體時代,大多數的軟體都會進行程式碼混淆、加殼等手段來保護自己的程式碼。Java和.NET都有對應的混淆器。黑客們對這個當然也不陌生,許多病毒程式為了反查殺,也會進行高度的混淆。只不過由於js是動態指令碼語言,在http中傳輸的就是原始碼,逆向起來要比打包編譯後的軟體簡單很多,很多人因此覺得混淆是多此一舉。

.NET混淆器dotFuscator

 

其實正是因為js傳輸的就是原始碼,我們才需要進行混淆,暴露在外的程式碼沒有絕對的安全,但是在對抗中,精心設計的混淆程式碼能夠給破壞者帶來不小的麻煩,也能夠為防守者爭取更多的時間,相對於破解來說,混淆器規則的更替成本要小得多,在高強度的攻防中,可以大大增加破解者的工作量,起到防禦作用。從這個角度來講,關鍵程式碼進行混淆是必不可少的步驟。

 

3、如何進行js混淆

 

js混淆器大致有兩種:

· 通過正則替換實現的混淆器

· 通過語法樹替換實現的混淆器

第一種實現成本低,但是效果也一般,適合對混淆要求不高的場景。第二種實現成本較高,但是更靈活,而且更安全,更適合對抗場景,我這裡主要講一下第二種。基於語法層面的混淆器其實類似於編譯器,基本原理和編譯器類似,我們先對編譯器做一些基本的介紹。

 

名詞解釋

 

token: 詞法單元,也有叫詞法記號的,詞法分析器的產物,文字流被分割後的最小單位。

AST: 抽象語法樹,語法分析器的產物,是原始碼的抽象語法結構的樹狀表現形式。

編譯器VS混淆器

 

編譯器工作流程

簡單的說,當我們讀入一段字串文字(source code),詞法分析器會把它拆成一個一個小的單位(token),比如數字1 是一個token, 字串'abc'是一個token等等。接下來語法分析器會把這些單位組成一顆樹狀結構(AST),這個樹狀結構就代表了token們的組成關係。比如 1 + 2 就會展示成一棵加法樹,左右子節點分別是token - 1 和token - 2 ,中間token表示加法。編譯器根據生成的AST轉換到中間程式碼,最終轉換成機器程式碼。

對編譯器更多細節感興趣的同學可以移步龍書:編譯原理

 

混淆器工作流程

編譯器需要把原始碼編譯成中間程式碼或者機器碼,而我們的混淆器輸出其實還是js。所以我們從語法分析之後往下的步驟並不需要。想想我們的目標是什麼,是修改原有的js程式碼結構,在這裡面這個結構對應的是什麼呢?就是AST。任何一段正確的js程式碼一定可以組成一顆AST,同樣,因為AST表示了各個token的邏輯關係,我們也可以通過AST反過來生成一段js程式碼。所以,你只需要構造出一顆AST,就能生成任何js程式碼!混淆過程如上右圖所示

通過修改AST生成一個新的AST,新的AST就可以對應新的JavaScript程式碼。

 

規則設計

知道了大致的混淆流程,最重要的環節就是設計規則。我們上面說了,我們需要生成新的AST結構意味著會生成和原始碼不一樣的js程式碼,但是我們的混淆是不能破壞原有程式碼的執行結果的,所以混淆規則必須保證是在不破壞程式碼執行結果的情況下,讓程式碼變得更難以閱讀。

具體的混淆規則各位可以自行根據需求設計,比如拆分字串、拆分陣列,增加廢程式碼等等。

參考:提供商業混淆服務的jscramble的混淆規則

 

實現

很多人看到這裡就望而卻步,因為詞法分析和文法分析對編譯原理要求較高。其實這些現在都有工具可以幫助搞定了,藉助工具,我們可以直接進行最後一步,對AST的修改。

市面上JavaScript詞法和文法分析器有很多,比如其實v8就是一個,還有mozilla的SpiderMonkey, 知名的esprima等等,我這裡要推薦的是uglify,一個基於nodejs的解析器。它具有以下功能:

    · parser,把 JavaScript 程式碼解析成抽象語法樹

    · code generator,通過抽象語法樹生成程式碼

    · scope analyzer,分析變數定義的工具

    · tree walker,遍歷樹節點

    · tree transformer,改變樹節點

對比下我上面給出的混淆器設計的圖,發現其實只需要修改語法樹 這一步自己完成。

 

例項

說了這麼多,可能很多人還是一頭霧水,為了幫助各位理解,我準備了一個簡單的例子,假設我們的混淆規則是想把 var a = 1; 中的數字1換成16進位制,我們該如何設計混淆器呢。首先對原始碼做詞法分析和語法分析,uglify一個方法就搞定了,生成一顆語法樹,我們需要做的就是找到語法樹中的數字然後修改成16進位制的結果,如下圖所示:

例項程式碼:

var UglifyJS = require("uglify-js");

var code = "var a = 1;";

var toplevel = UglifyJS.parse(code); //toplevel就是語法樹

var transformer = new UglifyJS.TreeTransformer(function (node) {

if (node instanceof UglifyJS.AST_Number) { //查詢需要修改的葉子節點

        node.value = '0x' + Number(node.value).toString(16);

        return node; //返回一個新的葉子節點 替換原來的葉子節點

    };

});

toplevel.transform(transformer);  //遍歷AST樹

var ncode = toplevel.print_to_string(); //從AST還原成字串

console.log(ncode); // var a = 0x1;

 

上面的程式碼很簡單,首先通過parse方法構建語法樹,然後通過TreeTransformer遍歷語法樹,當遇到節點屬於UglifyJS.AST_Number型別(所有的AST型別見ast),這個token具有一個屬性 value 儲存著數字型別的具體值,我們將其改成16進製表示,然後 return node 就會用新的節點代替原來的節點。

 

效果展示

貼一個我自己設計的混淆器混淆前後程式碼:

 

4、混淆對效能的影響

 

由於增加了廢程式碼,改變了原有的AST,混淆對效能肯定會造成一定的影響,但是我們可以通過規則來控制影響的大小。

    · 減少迴圈混淆,迴圈太多會直接影響程式碼執行效率

    · 避免過多的字串拼接,因為字串拼接在低版本IE下面會有效能問題

    · 控制程式碼體積,在插入廢程式碼時應該控制插入比例,檔案過大會給網路請求和程式碼執行都帶來壓力

 

我們通過一定的規則完全可以把效能影響控制在一個合理的範圍內,實際上,有一些混淆規則反而會加快程式碼的執行,比如變數名和屬性名的壓縮混淆,會減小檔案體積,比如對全域性變數的複製,會減少作用域的查詢等等。在現代瀏覽器中,混淆對程式碼的影響越來越小,我們只需要注意合理的混淆規則,完全可以放心的使用混淆。

 

5、混淆的安全性

 

混淆的目的是保護程式碼,但是如果因為混淆影響了正常功能就捨本逐末了。

由於混淆後的AST已經和原AST完全不同了,但是混淆後文件的和原檔案執行結果必須一樣,如何保證既兼顧了混淆強度,又不破壞程式碼執行呢?高覆蓋的測試必不可少:

    · 對自己的混淆器寫詳盡的單元測試

    · 對混淆的目的碼做高覆蓋的功能測試,保證混淆前後程式碼執行結果完全一樣

    · 多樣本測試,可以混淆單元測試已經完備了的類庫,比如混淆 Jquery 、AngularJS 等,然後拿混淆後的程式碼去跑它們的單元測試,保證和混淆前執行結果完全一樣

 

 總結

 

 

    · 可信web系統是我們的願景

    · 可信web系統離不開可信的前端環境

    · js混淆在對抗中必不可少

    · 實現一款自己的混淆器並沒有那麼難

    · 混淆器對效能的影響是可控的