Posted on 2009-12-03 23:17
深夜兩點 閱讀(1116)
評論(0) 編輯 收藏
(上一篇:計算機中的加密和認證http://www.tkk7.com/deepnighttwo/archive/2009/12/03 /304631.html)
A公司開發(fā)了一個軟件,打成了一個jar包,然后發(fā)布出去liao。作為一個用戶,如何來確認這個jar包確實是A公司發(fā)布的哪個?而且,如何確定這個jar包沒有被別有用心的一小撮篡改過?這就需要Java中的簽名來保證。
Java中的可執(zhí)行代碼就是class文件。直接使用class文件是很naive的。通常的做法是是對一個jar包中的所有class文件進行簽名。過程可以分為如下步驟。
- 首先使用JDK自帶的keytool工具生成一個keystore,命令如下: keytool -genkey -keystore keystore文件 -alias 別名?;剀嚭筮€有一些信息需要填寫。keystore里面包含了很多信息,包括公鑰和私鑰信息。當然可以使用keytool命令從keystore文件里面導(dǎo)出公鑰和私鑰。keytool命令還有很多參數(shù),比如你可以指定使用的摘要算法等。(具體用法可以Google之)。
- 然后,第二步當然是找個CA給公鑰簽名。自娛自樂的用途就可以不用這一步了。
- 第三步是給jar包簽名。JDK中提供了給jar包簽名的工具,叫做jarsinger。命令各式如下:jarsigner -keystore keystore文件 jar文件 別名(就是生成keystore時用的那個別名)?;剀嚭笠斎朊艽a,也跟生成keystore時候的密碼一樣就行了。
好,到這里就算簽名結(jié)束了。命令執(zhí)行完畢后,jar包會陡然多出幾k來。這幾k就是簽名的內(nèi)容。
Java(或者說是Java Runtime)是支持簽名和認證的。也就是說一個jar包一旦被簽名了,Java Runtime會對這個jar包進行驗證。下面是驗證簽名的過程。
首先需要知道簽名后jar包里面多出了什么。簽名并不會改變jar包中已經(jīng)有的內(nèi)容,而是添加了一個.DSA(說明使用的是DSA算法)文件和一個.SF(signed file)文件,然后在.MF文件里面增加一些內(nèi)容。驗證的過程是這樣的(我猜的。。。覺得不對可以去http://java.sun.com/javase/6/docs/technotes/guides/jar /jar.html,Sun公司的jar包規(guī)范,自己看自己猜),首先是DSA文件,它里面存儲了公鑰內(nèi)容和對SF文件摘要的加密內(nèi)容,所以,首先驗證公鑰(跟https里面的那個驗證是一樣的過程),驗證完畢證書后,用公鑰解密加密的內(nèi)容,然后得到SF文件的摘要值,把這個值和實際 SF文件的摘要值比較,這樣就可以保證SF文件沒問題了。SF文件里面的內(nèi)容包含了很多條目的簽名值。首先是對MF文件的簽名值,這就是驗證MF文件了。而MF文件里面對每個class文件都有一段描述的內(nèi)容,比如:
Name: common/class2.class
MD5-Digest: (base64 representation of MD5 digest)
SHA-Digest: (base64 representation of SHA digest
它代表這個class文件對應(yīng)摘要算法的摘要值。這個條目在SF里面有一個對應(yīng)的條目:
Name: common/class2.class
MD5-Digest: (base64 representation of MD5 digest)
注意,SF文件中的這個摘要值不是class文件的,而是MF文件里面對應(yīng)條目的。也就是說,SF里面的簽名值統(tǒng)統(tǒng)是用來驗證MF文件或者MF文件中的條目的,而MF文件中的摘要值才是用來驗證class文件的。真繞。。。
總之,最后一層層的驗證后,整個jar包中的內(nèi)容都被驗證了。過程:CA的證書->自己的公鑰->SF文件簽名 ->MF文件簽名和MF文件每個條目的簽名->jar包中的每個文件(當然主要是clas文件。別的文件應(yīng)該也會被驗證的,至少properties文件會被簽名認證)
驗證完了之后,就可以保證jar包確實出自某公司之手,也確實沒有被別有用心的一小撮人篡改過。如果你信任某公司,那就可以用這個jar包了。
同樣,如果一個applet的jar包是簽名了的,而且在啟動applet的時候用戶選擇信任這個簽名,那么這個applet就擁有了訪問本機資源的權(quán)限,如果選擇不信任,那么applet就不會被啟動。如果一個applet沒有被簽名,那么applet可以啟動,但是不會被允許訪問本機資源(文件等)。
如果一個證書沒有被CA的證書認證,比如說,對于我寫的這個applet,它就是用我自己搞出來的沒認證過的證書簽了名的:http://appletfarm.appspot.com/juliaappletsigned.html
這時候Java會提示說:

“該應(yīng)用程序的數(shù)字簽名無法驗證”,因為我沒給過VeriSign年費。如果證書是驗證過的,對話框就會是詢問你是否信任“某公司”,這個意思就是說,此jar包確實是“某公司”搞出來的,信任那個公司就可以運行它了。