移動代碼安全課件_第1頁
移動代碼安全課件_第2頁
移動代碼安全課件_第3頁
移動代碼安全課件_第4頁
移動代碼安全課件_第5頁
已閱讀5頁,還剩195頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第13章移動代碼安全13.1引言13.2移動代碼安全技術13.3Java安全第13章移動代碼安全13.1引言13.1引言移動代碼又稱移動代理、可下載代碼、可執(zhí)行內容、遠程代碼等等,它是指在本地執(zhí)行的遠程代碼。傳統(tǒng)系統(tǒng)中,執(zhí)行的代碼都是駐留在執(zhí)行代碼的主機上,而對于移動代碼,執(zhí)行的代碼則是來自遠程主機。Carzaniga等人[1]將移動代碼進行了分類并與傳統(tǒng)的基于客戶機—服務器技術的分布式系統(tǒng)作了比較:13.1引言移動代碼(1)客戶機—服務器模型:客戶機和服務器位于不同的主機上,由客戶機向服務器發(fā)送請求;處理請求所需的資源和代碼都位于服務器端。(2)即時響應代碼(Code-on-Demand):客戶機擁有完成某項操作的資源,但沒有如何完成這項操作的代碼,客戶機通過向遠程服務器發(fā)送請求,由服務器將代碼發(fā)送給客戶機。這種類型的移動代碼包括:Java應用程序、ActiveX控件、MIMITcl擴展和Postscript等。(1)客戶機—服務器模型:客戶機和(3)遠程計算:客戶機擁有描述某項服務的代碼,而執(zhí)行代碼所需的資源位于遠程服務器上。客戶機把代碼發(fā)送到服務器上,由服務器執(zhí)行代碼并把結果回送到客戶機。(4)移動代理:客戶機進程在執(zhí)行期間為了完成某項服務需要訪問一些資源,而這些資源位于遠程服務器上,于是客戶機把客戶機進程移植到服務器端并由服務器完成服務。客戶機進程會一直停留在服務器上直到下一個客戶機進程移植過來。(3)遠程計算:客戶機擁有描述某項Java應用程序(Applet)和代理(Agent)是移動代碼中的兩種主要形式。Java應用程序是用戶把代碼從遠程主機下載到本地執(zhí)行。這種技術在Web瀏覽器中嵌入了Java虛擬機。這樣,Web發(fā)布者就可以向用戶提供動畫、游戲等動態(tài)內容,而不僅僅提供靜態(tài)的HTML頁面或依賴于帶寬的CGI交互式內容。而代理則相反,用戶是把代碼發(fā)送到網絡上以完成用戶所需的某項任務。最早的移動代理系統(tǒng)之一是Telescript。Java應用程序(Applet)和從上面的討論可以看出,移動代碼是由一方生成,但在另一方控制的環(huán)境中運行的代碼。這就會帶來安全問題。如對于Java應用程序,用戶在執(zhí)行它來實現某些操作的同時要承擔惡意代碼破壞系統(tǒng)的風險,而代理則要保護其代碼免受惡意主機的利用。從上面的討論可以看出,移動代碼是由13.2移動代碼安全技術移動代碼會導致安全問題的本質在于在運行代碼時需要訪問系統(tǒng)資源,而代碼卻是來自于另一臺,甚至是不可信的主機。即代碼提供者和代碼運行者之間可能是互不信任的。移動代碼易受到以下幾種類型的攻擊[2]:(1)泄漏用戶或主機的機密信息;(2)拒絕服務:使合法用戶無法獲得資源;13.2移動代碼安全技術移動代(3)破壞或修改數據;(4)惡作劇攻擊:如在用戶屏幕上顯示圖片或在用戶主機上播放音樂等。(3)破壞或修改數據;移動代碼安全需要考慮以下幾個方面:(1)訪問控制:規(guī)定誰可以使用代碼;(2)用戶認證:識別合法用戶;(3)數據完整性:保證代碼在傳輸過程中未被修改過;(4)不可抵賴:發(fā)送者和接收方不能否認使用過代碼;(5)數據機密性:保護敏感數據;(6)審計:跟蹤移動代碼的使用。移動代碼安全需要考慮以下幾個方面:在前面提到,移動代碼安全可以從兩個方面考慮:一是惡意代碼對本地系統(tǒng)的破壞;二是遠程惡意主機對代理的非法使用。接下來,我們將從惡意代碼和惡意主機兩個方面來討論移動代碼的安全技術[3]。在前面提到,移動代碼安全可以從兩個方13.2.1惡意代碼對于Java應用程序類的移動代碼,一般的操作是用戶下載可執(zhí)行格式的二進制Applet然后運行。這就很容易帶來安全問題:用戶必須允許不可信的代碼在本機運行,而這些代碼可能會隨機寫內存,從而導致系統(tǒng)崩潰;代碼甚至可以讀、修改以至刪除用戶個人文件。在運行Applet之前進行認證可以解決這個問題。通過認證,用戶就可以確定它所運行的代碼來自于特定的可信源。但是這種方法帶來了兩個問題:13.2.1惡意代碼(1)嚴重限制了用戶可以運行的Applet(必須來自可信源),而不可信服務器也可提供有用的、好的代碼;(2)更重要的是來自可信源的代碼可能存在bug,從而對用戶系統(tǒng)帶來惡劣的影響。對這個問題的理想解決方法就是阻止不安全的行為。接下來討論三種解決惡意代碼問題的技術:安全解釋器、故障隔離和代碼驗證。(1)嚴重限制了用戶可以運行的App1.安全解釋器直接運行二進制代碼是很危險的,解決這個問題的常用方法是不使用編譯好的可執(zhí)行代碼,而采用解釋移動代碼的方法。在這種情況下,解釋器能很好地控制Applet并能檢查每一條指令和每一個狀態(tài)以決定是否執(zhí)行Applet。這樣,系統(tǒng)的安全性就在于實現解釋器的安全策略的正確性上。安全解釋器包括Safe-Tcl、Safe-Tcl擴展、Java等等。1.安全解釋器2.故障隔離采用安全的解釋器系統(tǒng)能很好地解決惡意代碼的問題。但是,相對編譯的機器碼而言,解釋器存在嚴重的性能缺陷:執(zhí)行JavaApplet比執(zhí)行一般的二進制代碼要慢得多。為此可以轉而采用一種稱為“沙盒”(sandbox)的方法來獲得安全。2.故障隔離在沙盒模式中,下載的不可信代碼的操作將嚴格局限于沙盒中。沙盒是由運行代碼的主機特別為移動代碼分配的地址空間,如Web瀏覽器特別為JavaApplet分配的區(qū)域。這時,移動代碼可以在沙盒中運行,但不會超出沙盒的界限。例如,Applet不能讀取或修改存儲在用戶系統(tǒng)上的文件。在某種情況下,即使用戶偶然引入了一個敵意的Applet,這個Applet也不能破壞用戶的系統(tǒng)。因此這種沙盒模式為移動代碼提供了一個受限的運行環(huán)境,在此環(huán)境中可以運行從開放網絡中獲得的不被完全信任的代碼(如Applet等)。在沙盒模式中,下載的不可信代碼的操作實現沙盒有兩種方法:(1)插入對地址進行條件檢查的操作,如果地址非法則產生異常;(2)簡單覆蓋對應沙盒地址的高比特位。第一種方法更適合調試,而第二種方法系統(tǒng)開銷小一些。采用沙盒模式的主要缺點是可下載的代碼不再是與平臺無關的,而與操作平臺無關原本是Java系統(tǒng)的主要設計目標之一。實現沙盒有兩種方法:3.代碼驗證第三種技術是一種稱為證明攜帶碼PCC(Proof-CarryingCode)的技術[4]。采用這種技術時,移動代碼主機為Applet確定安全策略,然后以Edinburgh邏輯結構(LogicalFramework:用來發(fā)布安全策略和對證明進行編碼)對安全策略編碼并發(fā)布這個策略。JavaApplet作者的任務不僅是把Applet編譯成機器代碼,還要產生一個安全證明(SafetyProof),用來證明這個代碼符合安全策略中指定的安全規(guī)則(SafetyRules)。

3.代碼驗證當用戶下載代碼后,它只要驗證代碼中的證明,看是否合法并滿足安全規(guī)則就行。如果是則加載代碼并運行它。這種方法是否有效的關鍵在于哪些程序特性可以用LF表示和證實。PCC已成功應用于最小和最大CPU周期限制、內存的安全使用、網絡帶寬消耗以及類型安全中。此外,為C語言的安全子集開發(fā)了PCC編譯器,它可以自動生成安全證明。當用戶下載代碼后,它只要驗證代碼中的PCC是一種很有前景的方法,但是,它也存在一些缺點:PCC與平臺有關;LF編碼的安全策略和安全證明必須和操作系統(tǒng)以及機器硬件密切聯系。更多信息可以參考網站:/pcc.html。PCC是一種很有前景的方法,但是,13.2.2惡意主機在討論了惡意代碼問題之后,我們開始討論惡意主機問題。在移動代理編程中,用戶所關心的是其代理能否被正確執(zhí)行。如一個購物代理可能會攜帶電子現金,一個主機就可能會欺騙代理使它為某些商品支付高價錢,甚至竊取代理內的金錢。這都是用戶所要面對的安全問題。主機為了執(zhí)行代理,需要訪問代理代碼和狀態(tài),那么如何保證敏感數據的機密性,或者說如何保證代理算法被忠實地執(zhí)行呢?Chess[13]等人認為保護移動代理的限制有:13.2.2惡意主機(1)要對代理代碼或狀態(tài)的任意部分保密,就必須采取加密;(2)我們無法阻止拒絕服務攻擊,因為攻擊者不需要專門可信硬件的幫助就可以任意修改代理代碼或終止代理。由此可見,要解決惡意主機問題就要從以下兩個方面著手:(1)能夠檢驗篡改;(2)能阻止機密信息泄漏。(1)要對代理代碼或狀態(tài)的任意部分保1.檢測篡改我們無法采用技術途徑來使代理不受破壞,但是如果能明確地識別出惡意主機,那么法律的、社會的威脅就可能阻止惡意主機的操作員破壞代理。識別惡意主機還可能使代理的所有者因代理的損失而獲得某種程度的補償。下面將介紹檢測惡意主機的技術,這些技術都是基于公開密鑰基礎設施的,它們允許用戶、主機和代理之間相互認證。這些技術主要是要證明一個主機確實是惡意主機,因此,采用數字簽名非常重要。1.檢測篡改(1)執(zhí)行跟蹤??梢酝ㄟ^產生代理程序執(zhí)行跡的方法來檢測篡改。首先,將代理代碼的指令分成兩類:只依賴于代理內部狀態(tài)的指令以及其結果依賴于和計算環(huán)境交互的指令。對于前一類指令,服務器只有在代理的任一變量的值發(fā)生變化時,才在執(zhí)行跡中記錄其新值;對于后一類指令,不但要記錄這些新值,還需要對這些值進行數字簽名。(1)執(zhí)行跟蹤??梢酝ㄟ^產生代理一旦執(zhí)行完畢,服務器就計算整個執(zhí)行跡的密碼散列值并將它返回給代理的所有者。這時,如果代理所有者懷疑在執(zhí)行代理時有違規(guī)操作,它就可以要求出示執(zhí)行跡,那么主機執(zhí)行代理時就必須生成執(zhí)行跡(執(zhí)行跡的散列值可被驗證),然后檢驗執(zhí)行跡就可確定:●主機是否錯誤地執(zhí)行了只依賴于內部狀態(tài)的指令;●主機執(zhí)行代理過程中,在與計算環(huán)境交互時是否欺騙了代理。一旦執(zhí)行完畢,服務器就計算整個執(zhí)行這種方法在實際的操作中存在兩個問題:(a)這種方法在主機違規(guī)操作時不會向代理所有者發(fā)出警報,而只有在所有者懷疑時提供一種可驗證的識別方法;(b)在需要生成執(zhí)行跡時,服務器需要保存所有的執(zhí)行跡,這就給服務器帶來了非常高的負擔。

這種方法在實際的操作中存在兩個問題:(2)認證部分結果。Yee[4]提出了兩種檢測惡意主機篡改代理的方法。第一種方法是采用部分結果認證碼(PRAC),發(fā)送代理的同時發(fā)送一組密鑰k1、k2、…、kn。在第i個服務器,代理使用密鑰ki對其執(zhí)行結果進行簽名并由此產生PARC;在轉移到下一個服務器之前,代理把ki從狀態(tài)中刪除。這樣,一個惡意主機就不能偽造來自前一個服務器的部分結果,最糟糕的情況也僅僅是把這些部分結果從代理中移除。(2)認證部分結果。Yee[4]PRACs允許代理所有者(同時擁有k1、k2、…、kn)自動地對返回代理中包含的每一部分結果進行密碼驗證。這些消息可以保證非常好的前向完整性:設移動代理訪問一系列的服務器S=s1、s2、…、sn,而第一個惡意服務器為sc,則對于i<c,服務器si的部分結果不是偽造的。當服務器僅僅通過與正在運行的代理進行欺詐性的交互實現篡改時,上述方案就無法自動檢測到。此外,只有在代理所有者懷疑主機時才會產生PRAC——所有的PRAC都是密碼有效的,但有些可能在語義上無效。PRACs允許代理所有者(同時擁有Yee提出了一種投機的方法來檢測語義上的篡改。對于程序x,設y為x的執(zhí)行跡。主機執(zhí)行完代理后把y發(fā)送給代理所有者,由所有者驗證y。由于執(zhí)行跡可能會很大,因此傳輸它的帶寬開銷會非常大。從而,主機把y編碼成全息樣片y'。樣片y'具有如下特性:代理所有者只需要檢查y'某些位就能確信其正確與否。這樣,服務器就可以采用哈希樹的方案將樣片散列成一個小的根值,然后把根值返回給代理所有者,由所有者判斷y是否正確。這種方法的主要缺點是服務器的負荷問題。構造全息樣片y'是一個全NP問題(不存在多項式時間算法解的一類問題,全NP問題則是最為困難的一類),在執(zhí)行跡y大到很難傳輸到代理所有者時,構造y'是不能實現的。Yee提出了一種投機的方法來檢測語義2.保密在有些情況下,事后檢測是不適當的或是不能解決問題的。如有時候采用法律行動的代價比篡改帶來的經濟損失更大;有些時候,代理發(fā)送數字簽名,但由于某些原因其私鑰已被泄漏。為此,Sander和Tschudin[13]提出了一種理論上的方案以允許代理對惡意主機保留一些機密。方案的本質是這樣的:代理程序計算某個函數f,主機為代理計算f(x)但不需要知道f的任何實質性的內容。協(xié)議描述如下:2.保密(1)代理所有者加密f;(2)所有者創(chuàng)建程序P(E(f))來實現E(f),并把它放在代理中;(3)代理到達遠程主機,在遠程主機上計算P(E(f))(x),并把值返回給所有者;(4)所有者解密P(E(f))(x)并獲得f(x)。其中,E為某個加密函數。協(xié)議的基本思想是把基本算法轉化成雜亂算法,使其結果只對代理所有者有意義。(1)代理所有者加密f;3.總結相比惡意代碼而言,惡意主機問題更難以處理,目前還沒有實際的、在計算上可行的方法用來檢測篡改,而一些可以用來證明發(fā)生了篡改的技術也會大大增加服務器的負荷。此外,在一個不友好的環(huán)境中運行代理時,有沒有可能為代理提供某種類型的機密性還是一個未知數。這些問題的存在或許可以解釋移動代理為什么得不到廣泛應用。3.總結13.3Java安全13.3.1Java綜述Java語言是SunMicrosystems公司開發(fā)的。在SunMicrosystems公司提供的技術報告[5]中稱:“Java是一種簡單的、面向對象的、適合網絡編程的、解釋的、健壯的、安全的、與結構無關的、可移植的、高性能的、多線程的動態(tài)語言?!?3.3Java安全13.3.1Jav●簡單:Java是一種易于使用的編程語言,其簡單性體現在以下幾個方面:(1)它和C++類似(C++程序員可以很快掌握Java編程技術);(2)它摒棄了C++中許多很少用、很難理解和容易混淆的特性,如操作符重載等;

●簡單:Java是一種易于使用的編(3)Java實現了自動垃圾收集,從而簡化了Java編程。在C和C++中,一個復雜的操作是內存管理:內存分配和內存釋放。通過自動垃圾收集(周期性的釋放沒有被引用的內存)不但可以使編程簡單化,還可大大地減少程序中的bug;(4)Java程序很小,易于通過網絡下載。(3)Java實現了自動垃圾收●面向對象:和C++一樣,Java是一種面向對象的編程語言。●適合網絡編程:Java擁有廣泛的、能輕易處理TCP/IP協(xié)議的運行庫,因此相比C和C++而言,Java更容易創(chuàng)建網絡連接。Java應用程序通過URL打開和訪問網絡上的對象與編程人員訪問本地文件系統(tǒng)一樣簡單?!窠研裕篔ava能檢查程序在編譯和運行時的錯誤。類型檢查可以檢查出許多開發(fā)早期出現的錯誤;Java沒有采用C++中的指針算法而實現了真數組,從而避免了覆蓋內存和破壞數據的可能?!衩嫦驅ο螅汉虲++一樣,Java●安全:設計Java是為了用于分布式網絡環(huán)境,因此安全在這里就顯得非常重要。本節(jié)的后續(xù)內容將詳細介紹Java的安全實現以及其潛在的安全威脅?!衽c結構無關:Java程序是在網絡上傳播和應用的,而網絡上的不同主機的CPU、操作系統(tǒng)結構等等都不盡相同,為了使Java應用程序能在網絡上的任何一臺主機上運行,編譯器必須產生一個與結構無關的文件格式——只要處理器上有Java虛擬機系統(tǒng),此文件格式的代碼就可以在此處理器上運行。Java的做法是讓編譯器生成與特定計算機體系結構無關的字節(jié)碼指令,這些字節(jié)碼指令在任何機器上都很容易解釋,并能很容易地翻譯成本機機器代碼。●安全:設計Java是為了用于分布●可移植:與體系結構無關的特性使得Java應用程序可以在配備了Java解釋器和運行環(huán)境的任何計算機系統(tǒng)上運行,這為Java應用程序便于移植打下了良好基礎。但僅僅如此還不夠,不同操作系統(tǒng)基本數據類型的設計實現是不同的,如在Windows3.1中整數(int)為16位,在Windows95中為32位,而在DECAlpha中卻為64位。這不利于代碼的移植。為此,Java定義了獨立于平臺的基本數據類型及其運算,從而使得Java數據在任何硬件平臺上都是一致的。其次,Java編譯器本身是用Java語言編寫的,而運算系統(tǒng)是用ANSIC語言寫的。總之,在Java語言規(guī)范中沒有任何與具體實現相關的內容?!窨梢浦玻号c體系結構無關的特性使●解釋:Java是一種解釋性語言,其解釋器可以將Java字節(jié)碼翻譯成本地機器指令并運行,而不需要存儲字節(jié)碼?!窀咝阅埽河捎诮忉屪止?jié)碼的性能一般都是比較高的,從而Java可以在運行時直接將字節(jié)碼翻譯成機器指令。SunMicrosystems的SPARCStation10在翻譯代碼時,可以在每秒鐘內調用300000個方法,這和直接生成機器目標代碼C/C++的性能不相上下?!窠忉專篔ava是一種解釋性語言,●多線程:Java提供了一個內建的機制來提供對多個并發(fā)子任務的支持。●動態(tài):在C++程序設計過程中,每當在類中增加一個實例變量或一種成員函數后,引用該類的所有子類都必須重新編譯,否則將導致程序崩潰,而Java是一種動態(tài)語言,它不是把所有的類靜態(tài)地編譯成機器碼,而是由程序動態(tài)地裝入運行過程中所需要的類?!穸嗑€程:Java提供了一個內建的13.3.2Java底層安全性實現1.底層安全Java解釋器通過以下幾種方式實現底層安全:1)通過發(fā)布源代碼獲得安全如果需要,Java解釋器和編譯器均可獲得完整的源代碼。對Java源代碼可以執(zhí)行安全審計。13.3.2Java底層安全性實現2)通過明確定義獲得安全Java語言的定義非常嚴格:●保證所有的基本類型使用指定的長度;●所有的操作必須按指定的順序執(zhí)行。明確的定義可以保證兩個(正確的)Java編譯器執(zhí)行同一個程序不會得到兩個不同的結果。2)通過明確定義獲得安全3)通過摒棄指針獲得安全Java摒棄了C語言中的指針算法,因此編程人員無法偽造指針來訪問內存。對類文件中所有方法和實例變量的引用都是通過符號名來實現的,這就可以避免在C語言中利用指針非法訪問內存而提升權限一類的攻擊,如緩沖區(qū)溢出等。

3)通過摒棄指針獲得安全4)通過垃圾收集獲得安全在C/C++中,編程人員經常面對的問題是內存分配和釋放。當釋放內存不當,如沒有釋放不再使用的內存或兩次釋放同一內存區(qū)會導致安全問題。Java通過自動垃圾收集(周期性地釋放沒有被引用的內存)來避免這些問題。4)通過垃圾收集獲得安全5)通過在編譯時的嚴格檢查獲得安全Java編譯器在編譯時要進行詳盡的、嚴格的檢查以盡可能地檢測編程中的錯誤。Java語言是強類型的:●在運行期,如果不進行明確的檢查不能把對象分配給某個子類;●要檢查所有對方法和變量的引用以確保對象具有合適的類型?!裾麛挡荒苻D換為對象,對象也不能轉換為整數。編譯器還要確保程序沒有訪問未初始化的本地變量。5)通過在編譯時的嚴格檢查獲得安全2.類文件驗證雖然編譯器可對類型進行詳盡的檢查,但攻擊者仍然可能通過使用專門的編譯器實現攻擊。如HotJava瀏覽器是下載已經編譯好的類文件,它無法確定下載的字節(jié)碼是由可信的Java編譯器編譯的還是由某個有惡意企圖的編譯器編譯的。

2.類文件驗證在編譯時實現對類型的檢查還存在版本不一致的問題。如用戶編譯好了一個類,假設PurchaseStockOptions是TradingClass的一個子類。但是在類編譯完后,TradingClass的定義可能會發(fā)生變化:某個方法不用了或方法的參數改變了;變量類型變了。而且,方法或變量也可能從公有變成私有。為此,所有外來的類文件都需要經過一個驗證器,由驗證器確保類文件具有正確的格式。在編譯時實現對類型的檢查還存在版本字節(jié)碼驗證器同樣可以增強解釋器的性能。利用字節(jié)碼驗證,解釋器就不用對每一條解釋的指令進行檢查,而會認為這些檢查都已經在此之前完成了。如解釋器能肯定代碼遵守以下限制:●代碼中不存在緩沖區(qū)溢出;●所有的寄存器訪問和存儲都是合法的;●所有字節(jié)碼的參數都是正確的;●不存在非法的數據轉換。字節(jié)碼驗證器同樣可以增強解釋器的性能驗證器獨立于Java編譯器,它使用戶可以放心的從防火墻之外下載Java代碼。下面詳細介紹驗證器的驗證過程,其中提到的類文件格式的具體細節(jié)可參考參考資料[5]:(1)驗證的第一步發(fā)生在將類讀入解釋器時。這一步要確保類文件具有類文件的格式:開始的幾個字節(jié)必須包含正確的魔幻數;所有可驗證的屬性都具有正確的長度;類文件的末尾不能被截斷,也不能添加額外的字節(jié);常數存儲庫不能包含不可識別的信息。

驗證器獨立于Java編譯器,它使用戶(2)第二步更進一步驗證類文件的格式:●確保final類沒有被繼承,final方法沒有被覆蓋;●每個類必須有一個超類;●確保常數存儲庫滿足一定的限制,如其中的類引用必須包含一個指向存儲庫中的一個unicode字符串引用的域?!癯荡鎯熘兴械挠蛞煤头椒ㄒ枚急仨氂泻戏ǖ拿?、合法的類和合法的類型簽名。(2)第二步更進一步驗證類文件的格式(3)這一步是類驗證中最復雜的一步,在這一步中需要驗證每一個方法的字節(jié)碼。這一步要保證:●堆棧的大小和它包含的對象類型保持不變;●除非已知包含了一個適當類型的值,否則不能訪問寄存器;●以適當的參數調用方法;●以適當類型的值修改域;●所有的操作碼在堆棧和寄存器中具有適當類型的參數。在“字節(jié)碼驗證”中我們將進一步描述這一步的細節(jié)。(3)這一步是類驗證中最復雜的一步,在這一步中需要驗證每一(4)在第三步中,除非有必要,否則不會裝載類文件。如一個方法調用另一個返回foobarType類型對象的方法時,如果立即把同一類型的域分配給返回的對象,驗證器就不會驗證foobarType類型是否存在;如果把anotherType類型的域分配給返回的對象,則必須裝載foobarType和anotherType的定義以確保foobarType是anotherType的一個子類。引用類的指令第一次執(zhí)行時,驗證器需:(4)在第三步中,除非有必要,否則●如果還沒有裝載這個類則裝載;●驗證當前正在執(zhí)行的類是否被允許引用給定的類。指令第一次調用方法或訪問、修改域時,驗證器需:●確保方法或域存在于給定的類中;●檢查方法或域是否具有要求的簽名;●檢查當前正在執(zhí)行的方法是否有權訪問給定的方法或域。●如果還沒有裝載這個類則裝載;這一步中,驗證器不需要檢查堆棧中對象的類型,因為在第三步中已經執(zhí)行了這項檢查。在執(zhí)行完驗證后,字節(jié)碼流中的指令就會被另一種形式的指令所代替。如操作碼new被new_quick代替。這個替換的指令表示已經執(zhí)行了對這個指令的驗證,不需要再次驗證了。這一步中,驗證器不需要檢查堆棧中對象3.字節(jié)碼驗證類文件驗證的第三步是字節(jié)碼驗證,這是類文件驗證過程中最復雜的一步。首先,把組成虛指令的字節(jié)分成一系列的指令,每一個指令開始位置的偏移量保存在一個位表中。然后,驗證器再次掃描這些字節(jié)并解析指令。這一步中把每個指令轉換成一個結構。檢查每個指令的參數(如果有的話)以確保它們是合理的:●所有的流程控制指令必須到達一個指令的開始,不允許有到達指令內部的分支。類似的,不允許出現到達代碼開始前或代碼結束后的分支。3.字節(jié)碼驗證●所有的寄存器引用必須是引用合法的寄存器。除方法指明的所能用的寄存器外,代碼不能訪問和修改任何其它的寄存器?!袼袑Τ荡鎯斓囊帽仨毷且眠m當類型的條目。如操作碼ldc1只能用于整數、浮點數或string類型,而操作碼getfield必須引用一個域?!翊a不能在某個指令中間結束。●對每一個異常處理程序,其起始點和結束點都必須指向一個指令的開始。異常處理器的偏移必須是合法的指令;起始點必須在結束點之前?!袼械募拇嫫饕帽仨毷且煤戏ǖ募膶γ恳粭l指令,在執(zhí)行之前,驗證器要跟蹤堆棧和寄存器的內容。對于堆棧,需要知道堆棧的長度和堆棧中元素的類型;對于寄存器,需要知道寄存器內容的類型或寄存器內的值是合法的。在確定堆棧中值的類型時,字節(jié)碼驗證器不需要區(qū)分不同的整數類型(如byte、short和char)。接下來初始化數據流分析器。對于第一條指令,編號較小的寄存器包含方法類型簽名所指示的類型;堆棧為空;所有其它的寄存器包含非法值;對于其它指令,指示該指令沒有被訪問,還沒有其堆?;蚣拇嫫鞯男畔?。對每一條指令,在執(zhí)行之前,驗證器要跟最后,運行數據流分析器。對每一條指令都有一個“changed”位來表示這個指令是否需要查看。最初只有第一條指令設置了“changed”位。數據流分析器執(zhí)行如下循環(huán):(1)找到一個設置了“changed”位的虛擬機器指令,如果沒有找到,則表示該方法已被驗證。清“changed”位。(2)仿真指令對堆棧和寄存器的影響:●如果指令要使用來自堆棧的值,需確保堆棧中有足夠的元素,并且堆棧頂端元素具有適當的類型,否則,驗證失敗。最后,運行數據流分析器。對每一條指●如果指令使用了寄存器,需確保指定的寄存器包含了適當類型的值,否則,驗證失敗?!袢绻噶钜阎祲喝攵褩#褩m敹思尤胫甘镜念愋?,需確保堆棧有足夠的空間存放新元素?!袢绻噶钚枰薷募拇嫫?,需說明寄存器當前包含了新的類型?!袢绻噶钍褂昧思拇嫫?,需確保指定的(3)確定跟隨在當前指令后面的虛擬機器指令。后續(xù)指令可能是:●如果當前指令不是無條件goto、return或throw,則為下一條指令;如果可以離開最后一條指令,則這一步失敗?!裼袟l件或無條件轉移的目標?!癞斍爸噶钏械漠惓L幚沓绦?。(3)確定跟隨在當前指令后面的虛擬(4)在當前指令的末尾,把堆棧和寄存器的狀態(tài)合并到下一條指令中。在異常處理的情況下,需要更改堆棧使得堆棧包含一個單一的對象,其異常類型由異常處理器信息指明?!袢绻乱粭l指令是第一次訪問,則在執(zhí)行下一條指令之前指明:由第(2)步和第(3)步計算得到的堆棧和寄存器的值是堆棧和寄存器的狀態(tài);設置下一條指令的“changed”位。●如果指令以前訪問過,則把第(2)步和第(3)步計算得到的堆棧和寄存器的值合并到已有的值中;如果有改動則設置“changed”位。(4)在當前指令的末尾,把堆棧和(5)回到第(1)步。字節(jié)流分析器對某些指令和數據類型,如長整數、構建函數、異常處理程序、Try/Finally等的具體驗證過程可參考參考資料[6]。(5)回到第(1)步。13.3.3Java的沙盒模型傳統(tǒng)的操作系統(tǒng)允許應用程序對機器有完全的訪問,因此不能信任運行環(huán)境。為此,安全策略一般要求在運行一個程序之前,需要在某種程度上信任程序。如在運行從Web上下載的程序之前,安全策略要求對程序進行病毒檢查以及檢查源代碼以發(fā)現惡意代碼。這種方法存在兩個問題:13.3.3Java的沙盒模型(1)建立對應用程序信任的檢查在實際操作中非常復雜,且非常費時間。一般人們不會花時間去研讀源代碼以發(fā)現隱藏在其中的惡意行為。(2)要使病毒檢查有效,需要及時地維護:病毒庫要及時更新、掃描程序要安裝在每一臺計算機上等等。(1)建立對應用程序信任的檢查在實Java采用了一種新的方法:沙盒。Java把Applet的所有操作都嚴格限制在一個稱之為“沙盒”(一個由Web瀏覽器專門為這個Applet分配的地址空間)的區(qū)域內。Applet在其沙盒內可以做任何事,但超出此邊界就不能有任何操作。沙盒模型實現了在一個信任環(huán)境中運行不信任的代碼的功能。這樣,即使用戶運行了一個惡意的Applet,也不會給用戶帶來什么損失。沙盒由幾個不同的系統(tǒng)操作組成,下面將逐一介紹。Java采用了一種新的方法:沙盒。1.類裝載程序ClassLoaderJava運行時有兩種不同的方式來裝載一個新的類。其默認機制是從本地機器上的文件中裝載一個類,這種機制不需要類裝載程序ClassLoader。另一種方式是通過網絡等裝載一個類,這時需要一個相關的類裝載程序ClassLoader,由ClassLoader負責將類的原始數據(如網絡上傳輸的字節(jié))轉化成表示那個類的內部數據結構。1.類裝載程序ClassLoade類裝載程序除了要完成從網絡上獲得一個Applet的可執(zhí)行代碼外,還實施了命名空間的體系結構。一個命名空間規(guī)定了一個Applet能訪問JVM(Java虛擬機)的其它哪些部分。通過為本地磁盤上的可信任代碼維護一個單獨的命名空間,類裝載程序可以防止不可信的Applet獲得對系統(tǒng)可信部分(往往需要更多特權才能訪問)的訪問權。從網絡上下載的Applet不能創(chuàng)建其自己的類裝載程序,也不能調用系統(tǒng)類裝載程序中的方法。類裝載程序除了要完成從網絡上獲得一2.驗證器在運行一個新下載的Applet之前,類裝載程序要調用驗證器進行類文件驗證。3.安全管理器安全管理器增強沙盒的邊界。在Applet試圖執(zhí)行可能導致本地機器崩潰或訪問信息的操作時,JVM首先向安全管理器詢問此操作是否可以安全地執(zhí)行。只有安全管理器準許了這項操作,虛擬機才能執(zhí)行,否則,虛擬機將產生一個安全異常并向Java控制臺寫出錯信息。2.驗證器下面列舉了安全管理器禁止不可信Applet執(zhí)行的部分操作:●對本地文件的讀寫;●刪除文件;●執(zhí)行操作系統(tǒng)命令或本地代碼;●載入一個直接調用本地方法的新的動態(tài)庫;●與不是此Applet源主機的機器建立連接;●建立一個新的進程。下面列舉了安全管理器禁止不可信Applet執(zhí)行的部分操作:一個應用程序或Web瀏覽器只能有一個安全管理器,這可保證所有的訪問檢查都是由一個執(zhí)行單一安全策略的安全管理器來完成的。安全管理器在啟動時載入,它不能被擴展、重載或替代。顯然,Applet不能創(chuàng)建其自身的安全管理器。4.語言特性在Java底層安全性實現一節(jié)中,我們可以看出,Java具有許多可以保護安全系統(tǒng)完整性,并防止某些常見攻擊的特性。

一個應用程序或Web瀏覽器只能有一13.3.4擴展Java安全Java沙盒模型可以保護終端用戶機器和網絡計算資源不受惡意Applet的破壞和進行信息竊取,從而用戶可以運行來自網絡上的不可信代碼而不會有安全風險。但是沙盒模型沒有涉及其它的一些安全和保密性問題:●認證可以幫助確認一個Applet確實來自其聲明的主機;●數字簽名和認證過的Applet可以提升為可信Applet,從而可以在較少的安全限制前提下運行;●加密可以保證Applet客戶端和Internet上服務器之間傳輸數據的機密性。13.3.4擴展Java安全1.簽署JAR文件所有的網絡化系統(tǒng)都容易受到潛在的中間人攻擊。在這種攻擊中,客戶端與網絡上的合法服務器進行連接并請求某種操作;而攻擊者,即這里所說的中間人竊聽到這些請求后就等待服務器的響應,然后截獲響應并向客戶端發(fā)送一個偽造的應答;這時客戶端就會根據這些偽造的信息進行某種操作,或者運行攻擊者提供的程序而使攻擊者獲得對機器的訪問權。如攻擊者可觀察一個基于Internet的銀行站點;當客戶端訪問其提供付款服務的頁面時,攻擊者就可以截獲銀行的響應,而把一個可以模仿銀行服務并可竊取用戶信用卡副本和銀行賬號的惡意Applet作為響應發(fā)送給客戶。1.簽署JAR文件通過對Applet使用“數字簽名”可以阻止這種攻擊。首先,把所有Java代碼和相關文件捆綁成一個Java檔案(JAR);然后根據JAR的內容利用數字簽名算法產生一個用字符串表示的數字簽名。通過驗證其數字簽名就可以確定這個JAR的來源,從而有效地防止了中間人攻擊。JAR文件從某種程度上還可幫助解決另外一個問題。目前,許多JavaApplet需要很長時間才能下載下來。這和當前的Internet協(xié)議有關。通過對Applet使用“數字簽名”可以目前的Internet協(xié)議每次只請求和傳送一個文件,每請求一個文件需要一定的開銷,而一個頁面和JavaApplet一般都由許多小文件組成,從而可能使得請求文件和等待響應的時間比真正傳輸信息的時間還要長。采用JAR文件后,把Applet和Web頁所需要的所有信息捆綁成一個文件,從而請求整個頁面就只需要一個請求。對于大部分的頁面,這可大大減少下載時間。目前的Internet協(xié)議每次只請2.靈活的策略數字簽名可以賦予JavaApplet某種可信度,從而可以放寬對某些Applet的Java安全限制。如上面提到的家庭銀行Applet,如果采用了數字簽名,它就可以在用戶硬盤上建立自己目錄以存儲賬號、信用卡號、口令、個人身份號碼PIN和其它經常要用的信息,這時的終端用戶不必經常性地重輸這些信息。2.靈活的策略數字簽名過的Applet可以創(chuàng)建自己的環(huán)境。如果終端用戶已提前指示Java系統(tǒng)某個特定的Web發(fā)布者是可信的,而且某個來自此Web發(fā)布者并簽名了的Applet被驗證通過,則Java安全管理器就可允許這個Applet的操作超出其沙盒的范圍,也就是說,把這個Applet看成一個普通的應用程序。數字簽名過的Applet可以創(chuàng)建自安全管理器還可以根據對特定Web發(fā)布者的信任程度或對整個Internet的信任程度而執(zhí)行不同的控制策略。如一個安全意識很強的用戶可能將系統(tǒng)配置成簽名了的Applet只能在沙盒范圍內執(zhí)行;未簽名的Applet根本就不允許執(zhí)行。另外一個用戶可能將系統(tǒng)配置成銀行Applet只能訪問硬盤上的某個特定目錄,而一個網絡游戲Applet可以訪問另外一個目錄,同時所有其它的Applet只能在沙盒的范圍內執(zhí)行。安全管理器還可以根據對特定Web發(fā)布3.審計審計是另一個重要的安全要素。審計軟件將維護系統(tǒng)上發(fā)生的每一件事的記錄。當出現錯誤時(無論是偶然還是由于bug,或者是由于攻擊造成的),系統(tǒng)管理員和安全人員就可以根據審計跡推測出所發(fā)生的事,從而可以幫助他們確定如何防止錯誤的再次發(fā)生。雖然審計不能阻止事故和攻擊,但在錯誤發(fā)生后,它是把事情弄清楚的重要工具。目前版本的Java審計功能很有限,還沒有管理員可以依賴的審計能力,而且其記錄的特征很不詳細。3.審計4.加密雖然沙盒模型和對Applet的數字簽名可以阻止惡意Applet的破壞和中間人攻擊,但在Internet上,Applet和服務器之間的信息傳輸仍然易遭到竊聽。這是因為Internet本身就是一個不安全的傳輸煤質。攻擊者在Internet的關鍵點可以獲得經過該關鍵點的所有的信息。由此,攻擊者可以偵聽出入一個銀行的所有流量,也可以只獲取通過的信用卡號和其它一些信息。為了防止這種攻擊,我們需要對Applet和服務器之間的所有流量進行加密,從而使它不可讀。4.加密13.3.5Java安全開發(fā)建議雖然Sun聲稱Java是一種安全語言,而且Java也采用了一些安全結構以及內建了一些安全特性,但是Java仍無法避免安全問題,其應用程序中仍存在大量的安全漏洞和隱患。為了使用Java開發(fā)安全的程序,可參考以下建議[10][11][12]。13.3.5Java安全開發(fā)建議1)限制對類、方法和變量的訪問把類、方法和變量聲明為公有會給攻擊者提供潛在的入口。為此:(a)不要使用公共域或變量,把它們聲明為私有的,并提供訪問函數以限制對它們的訪問;(b)除非有很好的理由,否則把方法都設為私有的(如果確實沒這樣做,說清楚其理由)。非私有的方法可能會接收受污染的數據,因此必須保護這些方法(除非已經用其它方式對它們進行了保護)。1)限制對類、方法和變量的訪問2)避免使用靜態(tài)域變量靜態(tài)域變量是附著在類而非類的實例上,而類可以被其它類所定位,其結果就是可以通過其它類找到靜態(tài)域變量,這就很難保證它們的安全。3)永遠不要把可變對象返回給潛在的有惡意代碼(因為代碼可能會改變它)注意,數組是可變的(即使數組的內容不可變),所以不要返回一個含有敏感數據的內部數組的引用。2)避免使用靜態(tài)域變量4)永遠不要直接保存用戶給定的可變對象(包括對象的數組)如果直接保存用戶給定的可變對象,用戶可以把對象交給安全代碼,讓安全代碼“檢查”對象,并在安全代碼試圖使用數據時改變數據。應該在內部存儲數組前復制它們,而且要小心(例如,警惕用戶編寫的復制例程)。4)永遠不要直接保存用戶給定的可5)不要依賴于初始化許多Java開發(fā)人員認為如果不運行構建器就無法為一個對象分配內存,這是不對的,事實上有許多方法可以為未初始化的對象分配內存。避免這個問題的一個簡單方法就是書寫自己的類,從而在對象進行某項操作前驗證對象。其做法為●使所有的變量為私有。如果要允許外部代碼訪問一個對象內的變量,可以通過set和get方法來實現(這就使外部代碼不能訪問未初始化的對象)。5)不要依賴于初始化●為每一個對象添加一個新的私有布爾變量initialized?!裨诜祷刂白屆恳粋€構建器設置初始化的變量作為最后一個操作?!裨谶M行進一步操作之前,讓每一個nonconstructor方法驗證initialized為真。●為每一個對象添加一個新的私有布爾變如果自己書寫的類具有靜態(tài)的初始化程序,則需要在類的層次做同樣的操作。也就是說,對于任何一個具有靜態(tài)初始化程序的類,需要:●使所有的靜態(tài)變量私有。如果要允許外部代碼訪問類中的靜態(tài)變量,可以通過靜態(tài)set和get方法來實現(這就使外部代碼不能訪問未初始化的靜態(tài)變量)。如果自己書寫的類具有靜態(tài)的初始化程序,●為類添加一個新的私有靜態(tài)布爾變量classInitialized?!裨诜祷刂白岇o態(tài)構建器設置初始化的變量作為最后一步操作。●在進行進一步操作之前,讓每一個靜態(tài)方法和每一個構建器驗證classInitialized為真。●為類添加一個新的私有靜態(tài)布爾變量6)除非有很好的理由,否則使每件事都final(終結)如果某個類或方法不是final的,攻擊者就可以用某種危險且無法預知的方法來擴展它。注意,作為安全性的交換,這會帶來可擴展性的喪失。7)不要在安全性上依賴包的范圍在同一個包內可以訪問沒有明確標記為public、private或protected的類、方法和變量。Java類不是關閉的,因此,攻擊者可以向包中引入一個新類,并用此新類來訪問用戶以為保護了的信息。(某些類,如java.lang,缺省是關閉的,而且某些Java虛擬機(JVM)會讓用戶關閉其它包,但最好假設包不是關閉的。)6)除非有很好的理由,否則使每件事8)不要使用內部類有些Java語言的書上稱只有封裝內部類的類才可以訪問被封裝的內部類,這是不正確的,因為Java字節(jié)碼沒有內部類的概念,在內部類轉換為字節(jié)代碼時,會被轉換為這個包中任意代碼可以訪問的類。更糟的是,被封裝類的私有域會靜悄悄地變成非私有的,從而允許內部類訪問!8)不要使用內部類9)最小化特權和避免標記代碼運行沒有標記的代碼不需要任何專門的特權。沒有專門特權的代碼不會帶來什么危害,為此應避免標記代碼。但是有時代碼需要獲得和使用特權以執(zhí)行某種危險的操作,此時應使代碼特權最小化,同時應更仔細地審閱特權代碼。9)最小化特權和避免標記代碼10)如果一定要標記代碼,應該把它們都放在一個檔案文件里此規(guī)則的目的是防止攻擊者使用混合匹配攻擊。在混合匹配攻擊中,攻擊者構建新Applet或庫,把某些標記類與有惡意的類連接在一起,或把根本意識不到會被一起使用的標記類連接在一起。通過把一組類標記在一起,就可以使這種攻擊更高明?,F有的代碼標記系統(tǒng)在防止混合匹配攻擊上做得還不夠,所以這一規(guī)則還不能完全防止此類攻擊。但使用單個檔案沒什么壞處。10)如果一定要標記代碼,應該把它11)使類不可被復制Java的類復制機制允許攻擊者不運行構建函數就實例化某個類。只要在每個類里定義如下方法就可使類不可被復制:publicfinalvoidclone()throwsjava.lang.CloneNotSupportedException{thrownewjava.lang.CloneNotSupportedException();}11)使類不可被復制如果確實需要使類可被復制,那么可以采用幾個保護措施來防止攻擊者重新定義復制方法。如果定義了自己的復制方法,就使它final;如果不是,至少可以通過增加如下內容來防止復制方法被惡意地重載:publicfinalvoidclone()throwsjava.lang.CloneNotSupportedException{super.clone();}如果確實需要使類可被復制,那么可以采12)使類不可順序化順序化可以使攻擊者看到對象的內部狀態(tài),甚至私有部分。攻擊者將對象順序化為可以讀的字節(jié)數組,這就使得他可以檢查對象所有的內部狀態(tài),包括標記為私有的域和引用對象的內部狀態(tài)。要防止這一點,需要在類里增加如下方法實現對象的不可順序化(定義成final方法是為了使攻擊者不能重載被攻擊者定義的子類):12)使類不可順序化privatefinalvoidwriteObject(ObjectOutputStreamout)throwsjava.io.IOException{thrownewjava.io.IOException("Objectcannotbeserialized");}在順序化沒問題的情況下,也應該對包含直接處理系統(tǒng)資源的域和包含與地址空間有關信息的域使用臨時關鍵字。否則,解除類的順序化就會造成不適當的訪問(可能還需要把敏感信息標識為臨時的)。privatefinalvoidwriteO如果對類定義了自己的順序化方法,就不應該把內部數組傳遞給需要數組的DataInput/DataOuput方法。其理由在于:所有的DataInput/DataOuput方法都可以被重載。如果某個可順序化的類向某個DataOutput(write(byte[]b))方法直接傳遞了一個私有數組,那么攻擊者就可以構建子類ObjectOutputStream并重載write(byte[]b)方法,從而可以訪問并修改那個私有數組。注意,缺省的順序化并沒有把私有字節(jié)數組域暴露給DataInput/DataOutput字節(jié)數組方法。如果對類定義了自己的順序化方法,就不13)使類不可被解順序化即使類不可被順序化,它依然可以被解順序化。攻擊者可以構建一個字節(jié)序列,使它碰巧可以解順序化為某個類實例,而且具有攻擊者選定的值。換句話說,解順序化是一種公共的構建函數,允許攻擊者選擇對象的狀態(tài)——顯然這是一個危險的操作!要防止這一點就需要防止能將一字節(jié)流解順序化為類的一個實例,這可通過聲明readObject方法來實現:13)使類不可被解順序化privatefinalvoidreadObject(ObjectInputStreamin)throwsjava.io.IOException{thrownewjava.io.IOException("Classcannotbedeserialized");}privatefinalvoidreadObject(14)不要通過名稱來比較類在Java中可以使用同一名字表示不同的類,這樣,攻擊者可以用相同的名稱定義類,同時可能會給這些類賦予不恰當的權限,因此,不要使用名字來比較類。下面是一個判斷某個對象是否含有某個給定類的錯誤方式:if(obj.getClass().getName().equals("Foo")){14)不要通過名稱來比較類如果確實需要判斷某個對象是否含有某個給定類名,則需要嚴格按照規(guī)范并確保使用當前名字空間(當前類的ClassLoader所在名稱空間)。因此,應該使用如下形式:if(obj.getClass()==this.getClassLoader().loadClass("Foo")){如果要判斷兩個對象是否含有完全相同的類,最好采用直接比較類對象的方法,即使用如下形式:if(a.getClass()==b.getClass()){如果確實需要判斷某個對象是否含有某個15)不要把秘密(密鑰、密碼或算法)存儲在代碼或數據里惡意JVM可以迅速看到這些秘密。打亂代碼并不能在高明的攻擊者面前真正隱藏代碼。15)不要把秘密(密鑰、密碼或算第13章移動代碼安全13.1引言13.2移動代碼安全技術13.3Java安全第13章移動代碼安全13.1引言13.1引言移動代碼又稱移動代理、可下載代碼、可執(zhí)行內容、遠程代碼等等,它是指在本地執(zhí)行的遠程代碼。傳統(tǒng)系統(tǒng)中,執(zhí)行的代碼都是駐留在執(zhí)行代碼的主機上,而對于移動代碼,執(zhí)行的代碼則是來自遠程主機。Carzaniga等人[1]將移動代碼進行了分類并與傳統(tǒng)的基于客戶機—服務器技術的分布式系統(tǒng)作了比較:13.1引言移動代碼(1)客戶機—服務器模型:客戶機和服務器位于不同的主機上,由客戶機向服務器發(fā)送請求;處理請求所需的資源和代碼都位于服務器端。(2)即時響應代碼(Code-on-Demand):客戶機擁有完成某項操作的資源,但沒有如何完成這項操作的代碼,客戶機通過向遠程服務器發(fā)送請求,由服務器將代碼發(fā)送給客戶機。這種類型的移動代碼包括:Java應用程序、ActiveX控件、MIMITcl擴展和Postscript等。(1)客戶機—服務器模型:客戶機和(3)遠程計算:客戶機擁有描述某項服務的代碼,而執(zhí)行代碼所需的資源位于遠程服務器上??蛻魴C把代碼發(fā)送到服務器上,由服務器執(zhí)行代碼并把結果回送到客戶機。(4)移動代理:客戶機進程在執(zhí)行期間為了完成某項服務需要訪問一些資源,而這些資源位于遠程服務器上,于是客戶機把客戶機進程移植到服務器端并由服務器完成服務。客戶機進程會一直停留在服務器上直到下一個客戶機進程移植過來。(3)遠程計算:客戶機擁有描述某項Java應用程序(Applet)和代理(Agent)是移動代碼中的兩種主要形式。Java應用程序是用戶把代碼從遠程主機下載到本地執(zhí)行。這種技術在Web瀏覽器中嵌入了Java虛擬機。這樣,Web發(fā)布者就可以向用戶提供動畫、游戲等動態(tài)內容,而不僅僅提供靜態(tài)的HTML頁面或依賴于帶寬的CGI交互式內容。而代理則相反,用戶是把代碼發(fā)送到網絡上以完成用戶所需的某項任務。最早的移動代理系統(tǒng)之一是Telescript。Java應用程序(Applet)和從上面的討論可以看出,移動代碼是由一方生成,但在另一方控制的環(huán)境中運行的代碼。這就會帶來安全問題。如對于Java應用程序,用戶在執(zhí)行它來實現某些操作的同時要承擔惡意代碼破壞系統(tǒng)的風險,而代理則要保護其代碼免受惡意主機的利用。從上面的討論可以看出,移動代碼是由13.2移動代碼安全技術移動代碼會導致安全問題的本質在于在運行代碼時需要訪問系統(tǒng)資源,而代碼卻是來自于另一臺,甚至是不可信的主機。即代碼提供者和代碼運行者之間可能是互不信任的。移動代碼易受到以下幾種類型的攻擊[2]:(1)泄漏用戶或主機的機密信息;(2)拒絕服務:使合法用戶無法獲得資源;13.2移動代碼安全技術移動代(3)破壞或修改數據;(4)惡作劇攻擊:如在用戶屏幕上顯示圖片或在用戶主機上播放音樂等。(3)破壞或修改數據;移動代碼安全需要考慮以下幾個方面:(1)訪問控制:規(guī)定誰可以使用代碼;(2)用戶認證:識別合法用戶;(3)數據完整性:保證代碼在傳輸過程中未被修改過;(4)不可抵賴:發(fā)送者和接收方不能否認使用過代碼;(5)數據機密性:保護敏感數據;(6)審計:跟蹤移動代碼的使用。移動代碼安全需要考慮以下幾個方面:在前面提到,移動代碼安全可以從兩個方面考慮:一是惡意代碼對本地系統(tǒng)的破壞;二是遠程惡意主機對代理的非法使用。接下來,我們將從惡意代碼和惡意主機兩個方面來討論移動代碼的安全技術[3]。在前面提到,移動代碼安全可以從兩個方13.2.1惡意代碼對于Java應用程序類的移動代碼,一般的操作是用戶下載可執(zhí)行格式的二進制Applet然后運行。這就很容易帶來安全問題:用戶必須允許不可信的代碼在本機運行,而這些代碼可能會隨機寫內存,從而導致系統(tǒng)崩潰;代碼甚至可以讀、修改以至刪除用戶個人文件。在運行Applet之前進行認證可以解決這個問題。通過認證,用戶就可以確定它所運行的代碼來自于特定的可信源。但是這種方法帶來了兩個問題:13.2.1惡意代碼(1)嚴重限制了用戶可以運行的Applet(必須來自可信源),而不可信服務器也可提供有用的、好的代碼;(2)更重要的是來自可信源的代碼可能存在bug,從而對用戶系統(tǒng)帶來惡劣的影響。對這個問題的理想解決方法就是阻止不安全的行為。接下來討論三種解決惡意代碼問題的技術:安全解釋器、故障隔離和代碼驗證。(1)嚴重限制了用戶可以運行的App1.安全解釋器直接運行二進制代碼是很危險的,解決這個問題的常用方法是不使用編譯好的可執(zhí)行代碼,而采用解釋移動代碼的方法。在這種情況下,解釋器能很好地控制Applet并能檢查每一條指令和每一個狀態(tài)以決定是否執(zhí)行Applet。這樣,系統(tǒng)的安全性就在于實現解釋器的安全策略的正確性上。安全解釋器包括Safe-Tcl、Safe-Tcl擴展、Java等等。1.安全解釋器2.故障隔離采用安全的解釋器系統(tǒng)能很好地解決惡意代碼的問題。但是,相對編譯的機器碼而言,解釋器存在嚴重的性能缺陷:執(zhí)行JavaApplet比執(zhí)行一般的二進制代碼要慢得多。為此可以轉而采用一種稱為“沙盒”(sandbox)的方法來獲得安全。2.故障隔離在沙盒模式中,下載的不可信代碼的操作將嚴格局限于沙盒中。沙盒是由運行代碼的主機特別為移動代碼分配的地址空間,如Web瀏覽器特別為JavaApplet分配的區(qū)域。這時,移動代碼可以在沙盒中運行,但不會超出沙盒的界限。例如,Applet不能讀取或修改存儲在用戶系統(tǒng)上的文件。在某種情況下,即使用戶偶然引入了一個敵意的Applet,這個Applet也不能破壞用戶的系統(tǒng)。因此這種沙盒模式為移動代碼提供了一個受限的運行環(huán)境,在此環(huán)境中可以運行從開放網絡中獲得的不被完全信任的代碼(如Applet等)。在沙盒模式中,下載的不可信代碼的操作實現沙盒有兩種方法:(1)插入對地址進行條件檢查的操作,如果地址非法則產生異常;(2)簡單覆蓋對應沙盒地址的高比特位。第一種方法更適合調試,而第二種方法系統(tǒng)開銷小一些。采用沙盒模式的主要缺點是可下載的代碼不再是與平臺無關的,而與操作平臺無關原本是Java系統(tǒng)的主要設計目標之一。實現沙盒有兩種方法:3.代碼驗證第三種技術是一種稱為證明攜帶碼PCC(Proof-CarryingCode)的技術[4]。采用這種技術時,移動代碼主機為Applet確定安全策略,然后以Edinburgh邏輯結構(LogicalFramework:用來發(fā)布安全策略和對證明進行編碼)對安全策略編碼并發(fā)布這個策略。JavaApplet作者的任務不僅是把Applet編譯成機器代碼,還要產生一個安全證明(SafetyProof),用來證明這個代碼符合安全策略中指定的安全規(guī)則(SafetyRules)。

3.代碼驗證當用戶下載代碼后,它只要驗證代碼中的證明,看是否合法并滿足安全規(guī)則就行。如果是則加載代碼并運行它。這種方法是否有效的關鍵在于哪些程序特性可以用LF表示和證實。PCC已成功應用于最小和最大CPU周期限制、內存的安全使用、網絡帶寬消耗以及類型安全中。此外,為C語言的安全子集開發(fā)了PCC編譯器,它可以自動生成安全證明。當用戶下載代碼后,它只要驗證代碼中的PCC是一種很有前景的方法,但是,它也存在一些缺點:PCC與平臺有關;LF編碼的安全策略和安全證明必須和操作系統(tǒng)以及機器硬件密切聯系。更多信息可以參考網站:/pcc.html。PCC是一種很有前景的方法,但是,13.2.2惡意主機在討論了惡意代碼問題之后,我們開始討論惡意主機問題。在移動代理編程中,用戶所關心的是其代理能否被正確執(zhí)行。如一個購物代理可能會攜帶電子現金,一個主機就可能會欺騙代理使它為某些商品支付高價錢,甚至竊取代理內的金錢。這都是用戶所要面對的安全問題。主機為了執(zhí)行代理,需要訪問代理代碼和狀態(tài),那么如何保證敏感數據的機密性,或者說如何保證代理算法被忠實地執(zhí)行呢?Ches

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論