巧用ASP技術保護DHTML原始碼 (轉)

worldblog發表於2007-12-08
巧用ASP技術保護DHTML原始碼 (轉)[@more@]

巧用技術保護


原作者: 松下客 01-5-25 下午 01:52:57


DHTML使得我們能夠開發出功能強大的應用客戶端,它具有跨相容、可互動和可移植等特點。它的缺點是能夠直接檢視script程式碼。本文介紹如何運用ASP技術保護DHTML程式碼,防止有人竊取你的DHTML程式碼。 傳統保護技術 眾所周知,Web本質上是一種不的媒介。當使用者訪問Web應用或者開啟Web頁面時,所有客戶端的程式碼(HTML,源以及CSS樣式)一般都要到客戶端緩衝區。使用者只需點選一下“檢視原始檔”就可以檢視、分析和複製這些程式碼。 MSDN摘錄了Wrox《Instant JavaScript》一書的部分內容,它指出了保護JavaScript程式碼的幾種方法,具體請參見.com/library/partbook/instantj/privacyforscriptwriters.htm?WROXEMPTOKEN=1925040ZHGWGH5B017qavIs1ts">這裡。 客戶端JavaScript程式碼保護方法主要可以分成如下幾類: a)Microsoft的方法:Microsoft透過釋出 Script Engine Version 5.0來解決客戶端原始碼保護問題。原始碼透過一個層編碼(不是)。請參見。 這種方法的缺點是經過編碼的程式碼只有5.0+才能解碼,而且他們坦率承認編碼過程並非簡單易行。如果你使用的是其他瀏覽器(包括IE瀏覽器的早期版本),你就不能透過瀏覽器訪問指令碼程式碼。 b)模糊程式碼(Code Obfuscation):一些共享,比如Jammer以及JMyth,企圖透過讓程式碼變得難於閱讀、讓變數名字變得雜亂去防止有人偷竊JavaScript程式碼。這種方法的缺點在於,任何有決心的員都能夠用全域性搜尋和替換工具輕鬆地打破這種保護,因為這隻需把那些含義模糊的變數名字改成含義明確的變數名字即可。關於JAMMER的更多說明,請參見。 c)加密:有許多方案、工具能夠有效地加密JavaScript程式碼。加密客戶端JavaScript程式碼最主要的問題在於用來的指令碼程式碼往往很容易取得,導致對程式碼實施反向工程非常容易。顯然,這種方法不能阻止任何認真的程式設計師獲取原始碼。雖然我們可以用Java作為加密和解密過程的中間工具,但遺憾的是,Applet會給Web頁面增加不必要的額外負荷,而且它會因為瀏覽器所用Java虛擬機器版本的不同而無法正常執行。相對而言,DHTML卻意味著、小巧、通用和可移植。 一種新方法 在試驗WML(Wireless Markup Language)時,我想到了一種保護客戶端原始碼的新方法。在基於ASP的WML頁面中,端程式碼會有如下內容: ? < % Response.ContentType = "text/vnd..wml" % > < ? version="1.0" encoding="iso-8859-1"? > < !DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "" > < wml > ...... ? 可以看到,我們首先傳送了一個WML頭,使得瀏覽器認為該ASP頁面實際上是一個WML頁面。這種技術同樣可以用來保護JavaScript原始檔(.js檔案)。 scape隨著JavaScript 1.2的釋出引入了對JavaScript原始檔的支援。大多數支援該版本JavaScript的瀏覽器都支援JavaScript原始檔(Internet Explorer 3.0+,Netscape 3.0+以及Opera 5.0)。動態HTML(DHTML)由JavaScript和CSS混合構成。CSS樣式使得開發者能夠自由地在瀏覽器視窗中表現各種頁面元素,而JavaScript則提供了控制瀏覽器本身的必要功能。JavaScript是DHTML的關鍵組成部分。 下面我們透過例子來說明這種新的DHTML原始碼保護方法。這個例子涉及三個檔案:index.asp,js.asp以及global.asa。global.asa定義了一個auth會話變數,該變數用於驗證請求JavaScript原始檔的頁面起源是否合法。這裡選擇使用會話變數的原因在於它用起來比較方便。 ? global.asa ? Sub Session_OnStart Session("auth") = False End Sub ? 我曾經試過用HTTP_REFERER變數來驗證發出請求的頁面起源是否合法,後來發現這個變數可以透過偽造,而且某些瀏覽器未能在執行時正確地顯示出HTTP_REFERER變數。 ? index.asp ? < % Session("auth") = True Response.Expires = 0 Response.Expiresabsolute = Now() - 1 Response.AddHeader "pragma","no-cache" Response.AddHeader "cache-control","private" Response.CacheControl = "no-cache" % > < html > < head > < title >測試頁面< /title > < script language="Javascript" type="text/javascript" SRC="js.asp" >< /script > < /head > < body > < script language="Javascript" >test();< /script > < br > < a href="index.asp" >reload< /a > < /body > < /html > ? 下面我們來分析一下index.asp。首先,程式把auth會話變數設定成了“true”,它表示請求.js檔案的頁面應該被信任。接下來的幾個Response防止瀏覽器快取index.asp頁面。 一般地,在HTML檔案中呼叫JavaScript原始檔的語法如下: ? < script language="Javascript" src="yourscript.js" >< /script > ? 但在本例中,我們呼叫的卻是一個ASP頁面而不是JavaScript原始檔: ? < script language="Javascript" type="text/javascript" SRC="js.asp" >< /script > ? 如果要遮掩應用正在請求ASP頁面這一事實,你可以把js.asp改名為index.asp(或者default.asp),然後把這個檔案放到單獨的目錄之中,比如“/js/”,此時上面這行程式碼就改為: ? < script language="Javascript" type="text/javascript" SRC="/js/" >< /script > ? 這幾乎能夠迷惑任何企圖獲取JavaScript原始檔的人了。不過,請不要忘記在IIS伺服器中正確地設定預設頁面檔案的名字。 ? js.asp ? < % IF Session("auth") = True THEN Response.ContentType = "application/x-javascript" Response.Expires = 0 Response.Expiresabsolute = Now() - 1 Response.AddHeader "pragma","no-cache" Response.AddHeader "cache-control","private" Response.CacheControl = "no-cache" Session("auth") = False % > function test(){ document.write('這是javascript的輸出.'); } < %ELSE% > < !--這些程式碼受版權保護。所有權利保留-- > < %END IF% > ? 下面我們來分析一下js.asp如何進行驗證以及傳送JavaScript程式碼。程式首先檢查會話變數auth,看看請求的起源是否合法。如是,則關閉瀏覽器快取,重新設定會話變數,然後向瀏覽器傳送JavaScript程式碼。如果對js.asp的請求不是來自可靠的起源,會話變數auth是false,程式只傳送一個帶有版權宣告的空白頁面。 其結果是,如果使用者企圖下載JavaScript原始檔或者在另一個網站上使用JavaScript原始檔,他得到的只是一個空白頁面。這樣,我們也就實現了對誰可以訪問DHTML原始檔的控制。 如果要在Web頁面中保護頁面實際內容的HTML程式碼,你可以在js.asp檔案中建立一個函式,如下所示: ? function html(){ document.write('< html >< body >頁面內容< /body >< /html > '); } ? 然後,主頁面只需簡單地呼叫一下html()即可構造出Web頁面。這種頁面只有在使用者啟用了瀏覽器的JavaScript支援之後才會顯示。如果使用者檢視這種頁面的原始碼,他看到的只有一個函式呼叫,而不會看到函式呼叫所返回的原始碼。 這種表現出兩種(或更多)不同型別檔案特徵的ASP可以稱為“混合ASP”。下面是JavaScript/ASP混合檔案的一些特點: ●JavaScript原始檔直接發向瀏覽器,未經快取。 ●檔案經過必要的驗證,防止了使用者下載原始碼。 ●終端使用者不能直接訪問原始碼。 上面的程式碼已經在、平臺的Personal Web Server以及4上進行了測試,在下列瀏覽器上程式碼均能流暢地執行:Netscape 4.7,Internet Explorer 5,Netscape 6以及Opera 5.0。 局?限 和任何其他技術一樣,本文所介紹的技術也有其固有的侷限。 ▲ 會話變數: 在上面的例子中,我們使用會話變數驗證JavaScript原始檔呼叫的起源。如果網站的訪問量非常高,這可能不是進行驗證的最好方法。 每次使用者訪問Web頁面或Web應用時都要建立一個會話變數。伺服器保持會話唯一識別符號的預設時間是20分鐘。如果伺服器同時要為大量訪問者維持狀態資訊,你可以想象出伺服器的負載會有多高。 解決這個問題主要有兩種方法: ●在伺服器上把會話超時時間設定得儘量小。此外,當程式碼已經傳送給瀏覽器之後,呼叫Session.Abandon釋放會話狀態資訊。這種方法適用於中小流量的網站。 ●對於高流量的網站,建議透過GUID/結合維持會話狀態的方法進行驗證。 ▲ 分配: 大多數基於的瀏覽器都用Sprmonkey JavaScript引擎解釋JavaScript。這個引擎的優點包括:以解釋方式執行程式碼(與編譯方式相對應),動態垃圾收集機制(換句話說,自動釋放記憶體空間避免記憶體吞噬資源)。 試試下面這個操作:執行上面的例子。函式執行之後,進入URL位址列,選中URL並敲Enter,你可以看到此時函式並不執行,瀏覽器顯示了一個JavaScript錯誤。然而,如果你點選瀏覽器的重新整理按鈕,函式將正常執行。 下面是產生這種情況的原因:JavaScript函式執行之後,由於瀏覽器假定需要時這些程式碼仍舊可以從快取獲得,於是它就釋放了為JavaScript保留的記憶體。然而,ASP程式碼禁止了瀏覽器快取JavaScript程式碼。由於瀏覽器不能再引用記憶體中的函式,也不能再從快取中獲取函式程式碼,所以你就在按Enter鍵時看到了一個錯誤。 點選瀏覽器的重新整理按鈕時,瀏覽器將重新從伺服器下載函式程式碼並執行。如果程式碼不再引用函式,則JavaScript引擎將釋放函式。但有一種方法可以強制瀏覽器在記憶體中保留函式,即在程式執行期間始終啟用對函式的引用。 ▲ 早期的/不相容的瀏覽器: 毫無疑問,本文所介紹的方法不適合JavaScript版本早於1.2的瀏覽器。解決辦法是編寫一個預先進行檢查的程式,由該程式檢查使用者瀏覽器是否和你的Web應用相容。 ▲ 包擷取: 理論上,只要企圖竊取程式碼的人具有足夠的決心,他可以在程式碼向瀏覽器傳送時透過竊取資料包竊取程式碼。然而,這項工作所要耗費的時間和精力使得它幾乎成為不可能的事情。而且,如果你想要獲得百分之百安全的傳輸,還可以使用。使用SSL唯一的缺點在於應用只能在支援SSL的瀏覽器上執行。 ■ 小結: “混合ASP”技術的應用當然不會侷限於ASP和JavaScript原始檔。在理論上,它可以在許多伺服器端指令碼語言環境中應用,比如CGI或者。此外,這種技術理論上還可以用於保護其他檔案,如圖形、和文件。例如,“混合ASP”檔案完全可以起到圖形檔案的作用,具體方法是先驗證請求的起源,向瀏覽器傳送正確的內容型別標識,然後從資料庫提取併傳送BLOB欄位的圖形檔案。它在這方面的應用可以說是沒有止境的。 在未來的許多年裡,JavaScript和DHTML仍將繼續發展,並繼續作為一種重要的Web開發工具而存在。有望認可客戶端工具的價值和重要性,併為了保護它而制定一個標準。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-989732/,如需轉載,請註明出處,否則將追究法律責任。

相關文章