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

代碼簽名和認證
    Java安全模型很重要的一點就是它能支持認證。認證可以使用戶確認,由某些團體擔保的一些class文件是值得信任的,並且這些class文件在到達用戶虛擬機的途中沒有被改變。
    
    要對一段代碼作擔保或者簽名,必須首先生成一個公鑰/私鑰對。用戶應該保管那把私鑰而把公鑰公開。至少,應該把公鑰給那些要在你的簽名上建立安全策略的人。一旦擁有了一個公鑰/私鑰對,就必須將要簽名的class文件和其他文件放到一個JAR文件中,然後使用一個工具(例如版本1.2 SDK中的jarsigner)對整個JAR文件簽名。這個簽名工具將首先對JAR文件的內容進行單向散列計算,以產生一個散列。然後這個工具將用私鑰對這個散列進行簽名,並且將經過簽名後的散列加到JAR文件的末尾。這個簽名後的散列代表了你對這個JAR文件內容的數字簽名。當你發佈這個包含簽名散列的JAR文件時,那些持有你的公鑰的人將對JAR文件驗證兩件事:這個JAR文件確實是你簽名的,並且在你簽名後這個JAR文件沒有做過任何改動。
    散列也被稱爲消息文摘,它相當於一種輸入“指紋”。
    單向散列算法是從大量數據(輸入)中產生少量數據(消息摘要或者散列),所以不同的輸入可能產生相同的散列。單向散列算法傾向於充分隨機地分佈產生相同散列的輸入,從而使產生相同散列值的概率主要依賴於散列的大小。
    (注:關於數字簽名、數字證書、非對稱加密算法、證書管理工具的一些基礎知識,原來的一篇文章簡單整理過,見小螞蟻-CAS單點登錄系列(1)-基礎知識


 
    要認證一個已簽名的JAR文件,接收者必須用公鑰對簽名散列進行解密,得到的結果應該和從JAR文件計算而得到的散列值相等。


  
 
一個代碼簽名示例
1)測試環境
Windows 7 + JDK 1.6
 
2)示例代碼
一個接口兩個類:
package com.artima.security.doer;

public interface Doer {
    void doYourThing();
}
 
package com.artima.security.friend;
import com.artima.security.doer.Doer;
import java.security.AccessController;
import java.security.PrivilegedAction;

public class Friend implements Doer {

    private Doer next;
    private boolean direct;

    public Friend(Doer next, boolean direct) {
        this.next = next;
        this.direct = direct;
    }

    public void doYourThing() {

        if (direct) {
            next.doYourThing();
        }
        else {
            AccessController.doPrivileged(
                new PrivilegedAction() {
                    public Object run() {
                        next.doYourThing();
                        return null;
                    }
                }
            );
        }
    }
}
 
package com.artima.security.stranger;
import com.artima.security.doer.Doer;
import java.security.AccessController;
import java.security.PrivilegedAction;

public class Stranger implements Doer {

    private Doer next;
    private boolean direct;

    public Stranger(Doer next, boolean direct) {
        this.next = next;
        this.direct = direct;
    }

    public void doYourThing() {

        if (direct) {
            next.doYourThing();
        }
        else {
            AccessController.doPrivileged(
                new PrivilegedAction() {
                    public Object run() {
                        next.doYourThing();
                        return null;
                    }
                }
            );
        }
    }
}
 
附件附帶了源代碼:samples.zip
 
3)編譯java文件
javac com\artima\security\doer\Doer.java
javac com\artima\security\friend\Friend.java
javac com\artima\security\stranger\Stranger.java
 
4)打包class文件
jar cvf friend.jar com\artima\security\friend\*.class
jar cvf stranger.jar com\artima\security\stranger\*.class
 
5)刪除class文件
刪除class文件,以便Java虛擬機在運行後面的訪問控制的例子時無法找到它:
del com\artima\security\friend\*.class
del com\artima\security\stranger\*.class
 
6)生成密鑰對並進行存儲
6.1)生成friend的密鑰對
命令:keytool -genkey -alias friend -keypass friend4life -validity 10000 -keystore ijvmkeys
keystore密碼:ijvm2ed
其他參數:
java
sun
sun
gz
gd
cn
y
 
(注:其中friend爲密鑰別名,friend的主密碼爲friend4life,有效期爲10000天,keystore文件名爲ijvmkeys。)
 
6.2)生成stranger的密鑰對
命令:keytool -genkey -alias stranger -keypass stranger4life -validity 10000 -keystore ijvmkeys -storepass ijvm2ed
參數:
java
sun
sun
gz
gd
cn
y
 
(注:storepass直接指明瞭1)中設置的keystore密碼)
 
7)現在keystore文件ijvmkeys包含了friend和stranger的密鑰對,下面對JAR文件進行簽名
jarsigner -keystore ijvmkeys -storepass ijvm2ed -keypass friend4life friend.jar friend
jarsigner -keystore ijvmkeys -storepass ijvm2ed -keypass stranger4life stranger.jar stranger
 
好了,爲了對兩個JAR進行簽名,必須做上面這許多事。
 
(轉載請註明來源:http://zhanjia.iteye.com/blog/1842242)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章