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