java 安全(一)

 Java語言本身嵌入了安全特性。比如 java 的類裝載機制,就使得外部定義的可疑的與jdk 內置的類同名的類是不被加載的。這裏主要是看了下java官方的安全性教程,記錄下過程。通過使用 jdk本身提供的tools 和 api 接口來做 數字簽名、證書、已經定義密匙庫等 已達到安全校驗的目的。使得遠程加載的 jar包 和 文檔 是可信任的。


假設,susan 是提供放,ray 是接受方。現在就通過 簽名機制保障雙方的數據傳輸的正確性


1: 提供方 Susan 定義自己的服務實現,編譯並打包成 jar包,已備傳輸使用


import java.io.*;

public class Count {
    public static void countChars(InputStream in) throws IOException
    {
        int count = 0;

        while (in.read() != -1)
            count++;

        System.out.println("Counted " + count + " chars.");
    }

    public static void main(String[] args) throws Exception
    {
        if (args.length >= 1)
            countChars(new FileInputStream(args[0]));
        else
            System.err.println("Usage: Count filename");
    }
}


假設 打包結果如下:

jar cvf Count.jar Count.class


2:生成密鑰庫

keytool -genkey -alias signFiles -keypass kpi135 -keystore susanstore -storepass ab987c

這裏會提示你輸入 Distinguished-Name 屬性。
然後會 產出一個密鑰庫的文件:susanstore 。密鑰庫裏面記錄的是一條條的 公鑰/私鑰 的對。

-alias signFiles 制定了引用密鑰庫的密鑰的別名。
-keypass kpi135  訪問密鑰的祕密
-keystore susanstore 密鑰庫的名字
-storepass ab987c  訪問密鑰庫的祕密

3:對提供服務的jar包進行簽名

jarsigner -keystore susanstore -signedjar sCount.jar Count.jar signFiles

這裏通過前面生成的 密鑰庫來進行簽名  sCount.jar 是簽名生成的jar包。這裏會提示密碼輸入才能夠使用 signFiles密鑰對 jar包進行簽名
store password (ab987c) and the private key password (kpi135).


4:導出公鑰證書已備接受 jar 放(ray)驗證使用

keytool -export -keystore susanstore -alias signFiles -file SusanJones.cer
這裏也會提示密碼輸入password (ab987c)
然後生成一個 公鑰證書 SusanJones.cer


對於接受方 Ray 來說,如果 制定安全管理的話,會提示沒有權限的異常現象

D:/study/security>java -Djava.security.manager -cp sCount.jar Count C:/TestData/data
Exception in thread "main" java.security.AccessControlException: access denied (java.io.FilePermission C:/TestData/data read)
        at java.security.AccessControlContext.checkPermission(AccessControlContext.java:323)
        at java.security.AccessController.checkPermission(AccessController.java:546)
        at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
        at java.lang.SecurityManager.checkRead(SecurityManager.java:871)
        at java.io.FileInputStream.<init>(FileInputStream.java:100)
        at java.io.FileInputStream.<init>(FileInputStream.java:66)
        at Count.main(Count.java:48)

如果Ray需要使得程序能夠正常的訪問本地文件,那麼他需要導入  Susan 提供的公鑰證書,並指定訪問權限

1: 導入 Susan 提供的 公鑰證書

keytool -import -alias susan -file SusanJones.cer -keystore raystore
將 Susan 提供的 公鑰證書 導入到Ray 本地的 密鑰庫 raystore
這裏會列出 證書的有效期 和 證書指紋: 通過比對 證書指紋 來驗證 Susan 提供的 簽名jar包是否可信任。
Susan 可以通過下面的命令來輸入 證書指紋:
keytool -printcert -file SusanJones.cer

2: 指定訪問權限 Susan 簽名過的jar包的訪問權限
raypolicy 文件內容如下:

keystore "file:/D:/study/security/ray/raystore", "jks";

grant signedBy "susan" {
  permission java.io.FilePermission "D://study//security//testdata//*", "read";
};

這裏指定 了 Susan 提供的簽名的文件具備訪問 D://study//security//testdata// 目錄下文件的 讀權限


下面Ray可以驗證簽名的文件的可信任度了。
java -Djava.security.manager -Djava.security.policy=raypolicy -cp sCount.jar Count D:/study/security/testdata/data

這裏有兩種方式: 一種是通過命令行參數 如上面的命令 -Djava.security.policy=raypolicy
另外一種是通過 java 的權限制定文件中設置 權限文件:
 jre.home/lib/security/java.security
添加權限文件:  policy.url.3=file:D:/study/security/raypolicy

新安全平臺中對足夠信任度的代碼放寬了限制,要獲得充分信任須通過代碼簽名來實現,若我們對某一簽名團體足夠信任,比如SUN,那麼具有該團體簽名的代碼將被給予充分信任。一個基本的思路大致爲,代碼發佈者創建私鑰/公鑰對,然後利用私鑰對發佈代碼進行簽名,代碼使用方在獲得代碼發佈者提供的公鑰後對代碼進行驗證,確認代碼確爲該提供者提供以及在發佈後未經非法修改。這其中存在一些潛在的危險,既是公鑰是否是該代碼發佈者提供的,惡意用戶可能替換掉合法的公鑰,這會導致用戶將給與惡意用戶發佈的代碼以充分信任,目前的常見做法是通過一些權威的證書機構來發布證書而不是公鑰,代碼發佈者被證書發佈機構認證合格後,可以將自己的公鑰交付證書發佈機構,證書發佈機構再通過私鑰加密該公鑰,從而生成證書序列。這樣替換公鑰的可能性就變得微乎其微。不過世上無絕對安全之事,通過證書機構發佈的證書也不是絕對安全的途徑。


參考 http://java.sun.com/docs/books/tutorial/security/toolsign/index.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章