深入理解Java虛擬機讀書筆記之:第3章 安全(1)

    爲了解決由網絡引起的安全問題,Java體系結構採用了一個擴展的內置安全模型,這個模型隨着Java平臺的主要版本而不斷髮展。

 
爲什麼需要安全性
    Java的安全模型是其多個重要結構特點之一,它使Java成爲適於網絡環境的技術。因爲網絡提供了一條攻擊連入的計算機的潛在途徑 ,因此安全性是非常重要的。
    Java安全模型側重於保護終端用戶免受從網絡下載的、來自不可靠來源的、惡意程序(以及善意程序中的bug)的侵犯。爲了達到這個目的,Java提供了一個用戶可配置的“沙箱”,在沙箱中可以放置不可靠的Java程序。沙箱對不可靠程序的活動進行了限制,程序可以在沙箱的安全邊界內做任何事,但是不能進行任何跨越這些邊界的舉動。
 
基本沙箱
    沙箱安全模型使得工作變得容易,即使某個軟件來自你不能完全信任的地方。沙箱模型使你可以接收來自任何來源的代碼,而不是要求用戶避免將來自不信任站點的代碼下載到機器上。但是當來自不可靠來源的代碼運行時,沙箱限制它進行可能破壞系統的任何動作。不必指出哪些代碼可以信任,哪些代碼不可以信任,也不必掃描查找病毒,沙箱本身限制了下載的任何病毒或其他惡意的、有漏洞的代碼,使得它們不能對計算機進行破壞。
    組成Java沙箱的基本組件如下
    1)類裝載器結構
    2)class文件檢驗器
    3)內置於Java虛擬機(及語言)的安全特性
    4)安全管理器及Java API
 
    Java的沙箱安全模型,最重要的優點之一就是這些組件中的類裝載器和安全管理器是可以由用戶定製的。通過定製這些組件,可以爲Java程序創建個性化的安全策略。
 
類裝載器體系結構
    在Java沙箱中,類裝載器體系結構是第一道防線。畢竟,是由類裝載器將代碼——這個代碼可能是惡意的或是有漏洞的——裝入Java虛擬機中。
    類裝載器體系結構在三個方面對Java的沙箱起作用:
    1)它防止惡意代碼去幹涉善意的代碼
    2)它守護了被信任的類庫的邊界
    3)它將代碼歸入某類(稱爲保護域),該類確定了代碼可以進行哪些操作
 
    類裝載器體系結構可以防止惡意的代碼去幹涉善意的代碼,這是通過爲由不同的類裝載器裝入的類提供不同的命名空間來實現的。
    在Java虛擬機中,在同一命名空間內的類可以直接進行交互,而不同的命名空間中的類甚至不能察覺彼此的存在,除非顯示的提供了允許它們進行交互的機制。


 
    在版本1.2中,類裝載器請求另一個類裝載器來裝載類型的過程被形式化,稱爲雙親委派模式。從版本1.2開始,除啓動類裝載器以外的每一個類裝載器,都有一個“雙親”類裝載器,在某個特定的類裝載器試圖以常用方式裝載類型以前,它會先默認地將這個任務“委派 ”給它的雙親——請求它的雙親來裝載這個類型。這個雙親再依次請求它自己的雙親來裝載這個類型。這個委派的過程一直向上繼續,直到達到啓動類裝載器,通常啓動類裝載器是委派鏈中的最後一個類裝載器。如果一個類裝載器的雙親類裝載器有能力來裝載這個類型,則這個類裝載器返回這個類型。否則,這個類裝載器試圖自己來裝載這個類型。
    因爲核心Java API的class文件是用於“啓動”Java虛擬機的class文件,所以,啓動類裝載器的名字也則得。


 
    在使用雙親-孩子委派鏈的方法中,啓動類裝載器會在最可信的類庫——核心Java API——中首先檢查每個被裝載的類型,然後,才依次到標準擴展、類路徑上的本地類文件中檢查。
 
    運行時包這個名詞,是在Java虛擬機第2版規範中第一次出現的,它指由同一個類裝載器裝載的、屬於同一個包的、多個類型的集合。在允許兩個類型之間對包內可見的成員(聲明爲受保護的或包訪問的成員)進行訪問前,虛擬機不但要確定兩個類型屬於同一個包,還必須確認它們屬於同一個運行時包——它們必須是由同一個類裝載器裝載的。
 
class文件檢驗器
    和類裝載器一起,class文件檢驗器保證裝載的class文件內容有正確的內部結構,並且這些class文件相互間協調一致。如果class文件檢驗器在class文件中發現了問題,它將拋出異常。
    因爲一個class文件實質上是一個字節序列,所以虛擬機無法分辨特定的class文件是由正常的Java編譯器產生的,還是由黑客特製的(黑客可能威脅虛擬機的完整性)。所以,所有的Java虛擬機的實現必須有一個class文件檢驗器,文件檢驗器可以調用class文件以確保這些定義的類型可以安全地使用。    
    class文件檢驗器實現的安全目標之一就是程序的健壯性。
    
    class文件檢驗器要進行四趟獨立的掃描來完成它的操作。
    1)第一趟:class文件的結構檢查
    第一趟掃描是在類被裝載時進行的,主要目的就是保證這個字節序列正確地定義了一個新類型,它必須遵從Java的class文件的固定格式,這樣它才能被編譯成在方法區中的(基於實現的)內部數據結構。
 
    2)第二趟:類型數據的語義檢查
    在這趟掃描中,檢驗器查看每個組成部分,確認它們是否是其所屬類型的實例,它們的結構是否正確。例如,方法描述符(它的返回類型,以及參數的類型和個數)在class文件中被存儲爲一個字符串,這個字符串必須符合特定的上下文無關文法。檢驗器對每個組成部分進行檢查的目的之一是,爲了確認每個方法描述符都是符合特定語法的、格式正確的字符串。
    另外,class文件檢驗器檢查這個類本身是否符合特定的條件,它們是由Java編程語言規定的。也就是說,class文件檢驗器在運行時檢查了一些Java語言應該在編譯時遵守的強制規則。(如,除Object類之外的所有類都必須有一個超類,final類沒有被子類化,final方法沒有被覆蓋等)
    
    3)第三趟:字節碼驗證
    在這趟掃描中,Java虛擬機對字節流進行數據流分析,這些字節流代表的是類的方法。爲了理解字節碼檢驗器,必須對字節碼和棧幀有一定的瞭解。
    字節碼流代表了Java的方法,它是由被稱爲操作碼的單字節指令組成的序列,每一個操作碼後都跟着一個或多個操作數。操作數用於在Java虛擬機執行操作碼指令時提供所需的額外的數據。執行字節碼時,依次執行每個操作碼,這就在Java虛擬機內構成了執行的線程。每一個線程被授予自己的Java棧,這個棧是由不同的棧幀構成的。每一個方法調用將獲得一個自己的棧幀——棧幀其實就是一個內存片斷,其中存儲着局部變量和計算的中間結果。在棧幀中,用於存儲方法的中間結果的部分被稱爲該方法的操作數棧。
    
    4)第四趟:符號引用的驗證
    在動態連接的過程中,如果包含在一個class文件中的符號引用被解析時,class文件檢驗器將進行第四趟檢查。在這趟檢查中,Java虛擬機將追蹤那些引用——從被驗證的class文件到被引用的class文件,以確保這個引用是正確的。因爲第四趟掃描必須檢查被檢測的class文件以外的其他類,所以這次掃描可能需要裝載新的類。大多數Java虛擬機的實現採用延遲裝載類的策略,直到類真正地被程序使用時才裝載。
    class文件檢驗器的第四趟掃描僅僅是動態連接過程的一部分。
 
    動態連接是一個將符號引用解析爲直接引用的過程。
 
二進制兼容
    正因爲Java程序是動態連接的,所以class文件檢驗器在第四次掃描中,必須檢查相互引用的類之間是否兼容。如果你修改了一個類,Java編譯器常會重新編譯這些類,從而在編譯時檢測是否有任何的不兼容性。
    Java語言規範中列出了用戶可以做的多種改動,這些改動稱爲二進制兼容性規則。
 
Java虛擬機中內置的安全特性
    1)類型安全的引用轉換
    2)結構化的內存訪問(無指針算法)
    3)自動垃圾收集(不必顯式地釋放被分配的內存)
    4)數組邊界檢查
    5)空引用檢查
 
安全管理器和Java API
    Java安全模型的前三個組成部分——類裝載器體系結構、class文件檢驗器以及Java中內置的安全特性——一起達到一個共同的目的:保持Java虛擬機的實例和它正在運行的應用程序的內部完整性,使得它們不被下載的惡意或有漏洞的代碼侵犯。相反,這個安全模型的第四個組成部分是安全管理器,它主要用於保護虛擬機的外部資源不被虛擬機內運行的惡意或有漏洞的代碼侵犯。這個安全管理器是一個單獨的對象,在運行的Java虛擬機中,它在訪問控制——對於外部資源的訪問控制——中起中樞作用。
    安全管理器定義了沙箱的外部邊界。因爲它是可定製的,所以它允許爲程序建立自定義的安全策略。當Java API進行任何可能不安全的操作時,它都會向安全管理器請求許可,從而強制執行自定義的安全策略。要向安全管理器請求許可,Java API將調用安全管理器對象的“check”方法。
    當Java應用程序啓動時,它還沒有安全管理器,但是,應用程序通過將一個指向java.lang.SecurityManager或是其子類的實例傳給setSecurityManager(),以此來安裝安全管理器,這個動作是可選的。
    當一個Java API即將進行一個潛在不安全的動作時,它將遵循以下兩個步驟。首先,Java API的代碼檢查有沒有安裝安全管理器,如果沒有安裝,則跳過第二步直接繼續這個潛在不安全的動作。否則,在第二步中,它將調用安全管理器中的合適的“check”方法。
    安全管理器負責兩個方面的工作:說明一個安全策略以及執行這個安全策略。
 
(轉載請註明來源:http://zhanjia.iteye.com/blog/1842144)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章