Java體系結構對資訊保安的支援

iteye_5228發表於2012-01-17
Java體系結構對資訊保安的支援
2010年06月09日
  Java語言擁有三大特徵:平臺無關性、網路移動性和安全性,而Java體系結構對這三大特徵提供了強大的支援和保證,本文著重介紹Java體系結構對支援資訊保安的原理和使用方法。 [b]Java體系結構[/b]
  首先Java的原始碼Java檔案由編譯器編譯成 Java的二進位制位元組碼class檔案,然後class檔案由Java虛擬機器中的類裝載器進行載入,同時類裝載器還會載入Java的原始 API Class檔案,類載入器主要負責載入、連線和初始化這些class檔案以後,就交給虛擬機器中的執行引擎執行,執行引擎將class檔案中的Java指令解釋成具體的本地作業系統方法來執行,而安全管理器將在執行過程中根據設定的安全策略控制指令對外部資源的訪問。
  Java的執行方式不是編譯執行而是解釋執行,不同平臺上面相同的原始碼編譯成符合Java規範的相同的二進位制位元組碼,然後再交給支援各自平臺的虛擬機器去解釋執行,"先編譯,後解釋,再執行"三步走的方式使得Java實現了"一次編寫,到處執行",如果Java應用使用的是100%標準Java API並且沒有直接呼叫本地方法,那就可以不加修改地運用在多種平臺上,這樣的平臺無關性使得在異構的網路環境或者嵌入式方面的應用更方便和現實。 Java的網路移動性帶來了一種全新的軟體模式,在分散式處理模式的基礎之上,可以將軟體和資料通過網路傳送到客戶端去,這樣確保了客戶端有必備的軟體來瀏覽和操縱通過網路傳輸的資料,Java體系結構支援把單一的執行檔案切割成小的二進位制位元組碼檔案Class檔案,而這些檔案可以按照應用的需要動態連線、動態擴充套件。Java體系結構對安全性的支援主要是通過Java語言本身安全性、虛擬機器的類載入器和安全管理器以及Java提供的安全API幾個方面來實現:防止惡意程式的攻擊,程式不能破壞使用者計算機環境;防止入侵,程式不能獲取主機或所在內網的保密資訊;鑑別,驗證程式提供者和使用者的身份;加密,對傳輸交換的資料進行加密,或者給持久化的資料進行加密;驗證,對操作設定規則並且進行驗證。
  [b] Java資訊保安的必要性[/b]
  隨著網際網路應用越來越廣泛,並且網際網路其本身獨特的資源共享性,因此能夠按照使用者需求及時準確獲得資訊和處理資訊的應用對使用者而言就相當重要,這也是Java得以迅速發展和被廣泛接受的原因。但同時網路也提供了一條攻擊接入計算機的潛在途徑,特別是當使用者下載網路軟體在本地執行,這就要求Java能夠對病毒/木馬的問題加以防範,對資訊以及本地環境進行保護。比如我們瀏覽一個網頁的時候,網頁上的Applet可能會自動下載並且執行,而這個Applet完全有可能來自不可靠的地方,又或者我們使用通過 JINI服務查詢到的網路上不可靠的服務物件來獲得服務,如果沒有Java體系結構提供的安全機制,這就很有可能引入了一個懷有敵意的程式造成資訊丟失、資料洩密、相信偽造資料和修改本地電腦保安設定等等後果,帶來未知的嚴重後果。
  [b] Java語言本身安全性[/b]
  Java語言的設計者們是在C++的基礎上設計出來 Java的,因此與C++相比它的語法更加簡單清晰,結構、單元、運算子過載、虛擬基礎類等在Java中都沒有采用,並且取消了多重繼承而採用實現多個介面的方式。這樣能降低開發人員犯錯誤的機率,幫助他們寫出更安全的程式碼。
  Java中去除了C++語言中的令人費解、容易出錯的"指標",用列表、堆、雜湊表等結構來代替,避免了任何不安全的結構。Java也沒有索引核查的陣列訪問,因為這往往會導致不定的、不可預測的程式操作,它所有的陣列訪問都必須先檢查是否越界。Java要求所有的變數在初始化以前不能使用,對於基本資料型別變數都會自動地賦給某個初始值,避免了未初始化變數獲取記憶體資訊。所有這些都使得程式不能訪問任意的記憶體地址,對於記憶體中的實體資訊只能通過有許可權的物件進行訪問,而不會出現象C++那樣把型別指標強制轉換成記憶體的指標,然後通過記憶體查詢的方法找到私有的變數。
  Java分配記憶體對於開發人員來說是透明的,開發人員使用new方法新建物件,這時候虛擬機器就會從堆記憶體中找到合適的記憶體空間,開發人員不需要也不能夠進行干預。而對於記憶體的回收,Java避免了開發人員明確干預物件的回收,比如C的free或C++的delete命令,避免了開發人員無意間對記憶體的破壞。Java採用虛擬機器的"垃圾回收"機制來實現的記憶體自動管理,釋放不再被使用的記憶體資源,記憶體回收器就像一臺垃圾收集車,但是和我們在大街上看到的收集車,僅僅收集大家放在垃圾桶裡面的垃圾不同的是,它還要到你家裡去幫你找出那些東西是不要用的垃圾,然後把這些東西拿走,最後還要整理家裡的空間,騰出最大的空間讓你放新東西。Java的記憶體回收器目的就是找到不再引用的物件,釋放記憶體空間,並且需要整理記憶體的碎片空間,儘量避免出現"記憶體不足"的情況。
  對於在網路中交換的序列化物件很容易在重建物件的時候訪問到物件的私有資訊,這時候Java提供了兩種辦法來保護資訊,一種就是採用給變數加上transient關鍵字的方法,這樣物件序列化的時候就不會讀寫該變數,另一種就是在實現Externalizable介面而不是Serizlizable介面,這樣物件就只能通過writeExternal和 readExternal方法來儲存和重建,其他方法無法進行了。
  以上這些都是Java語言本身對資訊保安提供的基礎。
  [b] 類載入器[/b]
  雖然名字叫類載入器,但是實際上Java虛擬機器中的類載入器不光要負責載入而且要負責連線和初始化應用程式需要用到的Java型別。載入就是把二進位制形式的位元組碼讀入虛擬機器中,而連線就是給這個已經讀入的型別分配類變數記憶體以及把型別中用到常量池中的符號轉換為直接引用,最後的初始化過程就是賦給型別變數合適的初始值。
  類載入器為載入的類提供了不同的名稱空間,統一原始碼生成的位元組碼被載入到同一個名稱空間中,相同名稱空間不能載入類名相同的類,同一個名稱空間內的類可以直接進行互動,而不同的名稱空間的類是不能互動的,除非顯式地提供了互動機制,通過名稱空間和類成員訪問許可權的設定保護了被信任的類邊界。
  類載入器分成了啟動類載入器、標準擴充套件類載入器、路徑類載入器和網路類載入器四種。啟動類載入器從本地系統中載入原始的Java API類,用來啟動Java虛擬機器,而其他三種載入器是在執行時載入使用者定義的類,標準擴充套件類載入器載入的是不同虛擬機器提供商擴充套件的標準Java類,而在 classpath中的類由路徑類載入器來載入,網路類載入器載入通過網路下載得到的類檔案,每一種載入器在載入類的時候都會建立一個載入器例項。類載入器採用雙親委派鏈模式(這個模式很類似GOF在《設計模式》一書中提到的責任鏈模式)除了啟動類載入器以外,每個類載入器都有自己的"雙親"。一個類可以通過有三種方法定義自己的雙親:第一種通過引用,比如A類中引用了B類(即A和B有關聯關係),那麼B類的載入器就會作為A類的載入器的"雙親",早於A 類載入;第二種使用loadClass方法來自定義"雙親",這時被load的類的"雙親"即本身這個類載入器;第三種在沒有采用前兩種的情況下使用的預設方式,預設把啟動類載入器作為"雙親"。
  在載入過程中,當發出載入請求的時候,載入器首先詢問它的"雙親"

相關文章