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