自從Java技術開始應用以來
人們對Java平台的安全性以及由於部署Java技術所引發的安全問題給予了極大的關注
特別是在
年
月Java
發布後
Java的安全體系結構發生了根本的改進
對於終端用戶而言
它可以保護文件和私人數據不被惡意的程序或病毒感染和破壞
鑒別代碼提供者的身份
對於開發者而言
通過使用API方法
能夠將安全性功能集成到應用程序中
因為API的體系結構能夠定義和集成對特定的資源的使用權限
加密
安全性管理
策略管理
並提供了一些類來管理公鑰/密鑰對及信任用戶群的公鑰證書
同時系統管理員
開發者和用戶可以使用它提供的工具管理鑰匙庫
在JAR文件中生成數字簽名
簽名的完整性檢測
創建和修改策略文件
按照Java設計者的觀點
Java安全包括
個方面的內容
首先將Java作為一種安全的平台提供給用戶
在此平台上
可安全地運行Java程序
其次提供用Java編程語言實現的安全工具和服務
它使得諸如企業界這樣一些對安全非常敏感的領域也可應用Java技術
本文將就這二個方面介紹Java
的安全性新特性以及該新特性下的Applet數字簽名的具體實現方法
Java
采用了如圖
所示的新的安全體系結構
並基於這種安全體系結構提供了很多新特?
.
密紋訪問控制
這種能力從一開始就在JDK中存在
但要使用它
應用程序的編寫者不得不做大量的編程工作例如
創建SecurityManager和Classloader類的子類並使其用戶化
HotJava
.
就是一個這樣的應用程序
它允許浏覽器用戶在幾個不同的安全等級上進行選擇
然而
這種編程涉及非常敏感的安全問題
它要求程序員對計算機安全有精深的理解和純熟的技巧
新的安全體系結構將使這些變得簡單而安全
.
易於配置的安全策略
與上述情況相似
這種能力在原來的JDK中也是存在的
但是不便於使用
而且編寫安全代碼也不是簡單明了的事情
於是
人們期望能夠允許應用程序的編寫者和用戶能夠不通過編程來設置安全策略
.
便於擴展的訪問控制結構
一直到JDK
.
為止
為了創建
個新的訪問許可
你必須在SecurityManager類中增加
個新的check方法
新的安全體系結構則允許設置各類訪問許可(每個都表示對
個系統資源的訪問)
並能對所有正確訪問許可(包括未定義的許可)進行自動處理
.
安全檢查擴展至所有Java程序
那種所有本地代碼是可信的內置概念將不復存在
取而代之的將是本地代碼(例如非系統代碼
安裝在本地的應用程序包等)服從於與Applet相同的安全控制
但是可以聲明對本地代碼的政策是最寬容的
從而使這些代碼可被認為是完全可信而有效地運行
上述原則也可應用於已簽字的Applet和任何Java應用程序
Java
安全體系的概念及運行機制
.
保護域
Java
安全體系結構中的一個基本的概念是保護域(Protected Domain)
個域可通過對象集來劃分范圍
這些對象當前可由
個主體直接訪問
而主體是在計算機系統中被授予許可的實體
JDK
.
所利用的沙箱就是一個有著固定邊界的保護域實例
保護域的概念是一種在保護單元間起著分組和隔離作用的便利機制
例如
我們可以將保護域分開以避免它們之間的直接交互作用
於是
任何允許的交互作用必須通過可信系統代碼或被有關的域所明確允許
保護域通常分為明確的
個類別
系統域和應用程序域
所有被保護的外部資源如
文件系統
網絡設施以及屏幕和鍵盤等僅能通過系統域來訪問
圖
中顯示了
個Java應用環境的域的組成
從概念上講
個域包括
組類
這些類的實例被授予相同的一組許可
保護域是由現行策略所確定的
Java應用程序環境保持了來自代碼(類和實例)到它們的保護域然後再到它們的許可的映射
如圖
所示
個線程的執行可能完全發生在
個單一的保護域中
也可能涉及
個應用程序域或是系統域
例如
個打印消息的應用程序將不得不與系統域發生交互作用
因為系統域是唯一對輸出流的訪問點
在此種情況下的任何時候
應用程序域都不能通過調用系統域獲得除打印消息外的任何額外許可
否則將是一個嚴重的安全性隱患
在相反的情形下
個系統域從
個應用程序域中調用
個方法
如當
個AWT系統域調用
個Applet的繪畫方法來顯示這個Applet時
有效訪問權限與應用程序域所允許的當前權限在任何時候都相同
這一點也是同樣至關重要的
換句話說
一個具有較低權限的域不能通過調用一個更高權限的域
或被一個更高權限的域所調用來獲得額外的許可
上述有關
個線程涉及
個保護域的討論自然地歸納為
個遍歷多重保護域的線程
計算許可的一個簡單而謹慎的經驗做法是
(
)一個執行線程的許可集可被認為是由該線程所遍歷的所有保護域的許可的交集
(
)當
條代碼調用doPrivileged方法時
執行線程的許可集被認為是包括所有代碼的保護域以及由它直接或間接調用的保護域的權限
即通過doPrivileged方法可使
條可信代碼能臨時訪問更多的資源
這在某些情況下是必要的
例如
個應用程序可能不被允許直接訪問包含字體的文件
但是
顯示文本的系統實用程序必須代表用戶獲得那些字體
在執行期間
當請求訪問
個關鍵系統資源(如文件I/O和網絡I/O)或者API方法需要執行
個敏感的操作時
例如讀
個文件
資源處理代碼直接或間接地調用
個特殊的稱為訪問控制(AccessController)類的方法
訪問控制類通過檢查調用棧來作出決定是否准予該請求或操作發生
在調用棧中是執行該操作需要調用的一些類的成員方法
因為每個類都屬於一些保護域
每個保護域都建立了一些策略
因此在調用棧的每個方法都被分配了
組權限
訪問控制類由棧頂開始
自頂向下檢查每個方法
看是否方法被所在的保護域所允許
如果發現一個方法權限沒有得到允許
訪問控制
就拋出安全性異常
反之
如果到達棧底仍未拋出異常
即說明調用棧中的所有方法均滿足保護域的權限要求
訪問控制允許操作發生
其中有一種特殊的情況
即當訪問控制遍歷調用棧時
將查找是否存在優先域(Privileged Domain)
如果存在優
域
即使沒有到達棧底
訪問控制也將停止遍歷調用棧並允許操作發生
雖然新的安
機制初看上去增加了許多調用API方法的消耗
但是Java
確實使用了一些技術去加速
查權限的過程
例如訪問控制將過濾掉重復的域並在遇到第一個優先域時停止檢查
說明額外的操作將是一個本地的方法調用
SUN的基准測試顯示了新的安全檢查是相當快的
最後
每個域包括系統或應用程序域可以對其域邊界內的內部資源進行附加保
例如
一個銀行系統的應用程序可能需要支持並保護其內部的一些概念
如查帳
存
和取款等
由於此種保護的語義不像那些可預測的語義可以被JDK預置
因而
在這個
次上的保護最好留給系統或應用程序開發員來做
目前
個域單獨地由
個代碼來源(CodeSource)鑒別
它封裝了在該域中運行的代碼的
個特性
代碼基址和公共密鑰證書集
公共密鑰對應於在該域中為所有代碼簽字的私有密鑰
因而
由相同的密鑰簽字和來自相同URL的類被放在同一個域中
個域還包含在該域中授予代碼的許可
它是由現行安全策略所決定的
.
證書
鑰匙庫及其相關工具
在Java
的安全體系下
個Applet開發和運行的過程如下
在代碼的分發端
(
)開發Java源程序並對其進行編譯
(
)用JAR工具對類文件和資源文件進行封裝
(
)用keytool創建公鑰和密鑰
生成X
V
簽名證書
輸出證書
(
)通過jarsigner工具用生成的密鑰對JAR文件進行數字簽名
在代碼的接收端
(
)用keytool輸入證書視其為可信任
(
)用policytool創建和修改安全性策略配置文件
授權請求的訪問權限
(
)從網絡取得字節碼
用公鑰驗證數字簽名證書和文檔代碼的完整性
(
)驗證字節碼的合法性
根據策略文件分配相應權限
(
)執行代碼
完成後被垃圾回收器回收內存
在用公鑰驗證數字簽名證書之前
接收方需要確認公鑰自身的可靠性
因此通常情況是提供一個包含公鑰的證書而不是公鑰自身
個證書包括
(
)
個公鑰
(
)
個唯一的名字實體(個人或公司)
它是證書的所有者
包含用戶名字
公司
組織
城市
地址
國家代碼
省份等信息
(
)數字簽名
個證書被
個分發者的實體簽名
保證證書確實包含另
個
實體(所有者)的公鑰
(
)分發者的標識名信息
對於接收者可以用分發者的公鑰來驗證他的數字簽名
檢查證書的合法性
然而公鑰可能包含在另一個證書中
而數字簽名需要用另一個證書的分發者的公鑰來驗證
這樣嵌套下去
直到一個公鑰被接收者確認是可信任的
如果接收者不能建立信任鏈
例如
個分發者的證書不合法
那麼可以用keytool-import命令來計算指紋
每個指紋是一個相關的短數字
它唯一可靠地標識證書(指紋是一個用信息摘要算法計算的證書信息的哈希值)
接收者可以呼叫證書的所有者
並比較發出的證書和接收證書的指紋
如果指紋相同
則證書不同
因此能夠保證證書在傳遞的過程中未被修改
另一個潛在的問題是發送者身份的標識
有時一
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26322.html