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

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

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

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

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

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

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

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

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

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

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

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論