安全--代碼簽名和認(rèn)證
代碼簽名和認(rèn)證
Java安全模型很重要的一點(diǎn)就是它能支持認(rèn)證,這是在Java 1.1的java.security包及其子包中引入的特性。
認(rèn)證功能加強(qiáng)了用戶的能力,使用戶能通過實(shí)現(xiàn)一個(gè)沙箱來建立多種安全策略,
這個(gè)沙箱可以依賴于為這個(gè)代碼提供擔(dān)保的對(duì)象來改變。
認(rèn)證可以使用戶確認(rèn),由某些團(tuán)體擔(dān)保的一些class文件是值得信任的,并且這些class文件在到達(dá)用戶虛擬機(jī)的途中沒有被改變。
這樣,如果用戶在一定程度上信任這個(gè)為代碼作擔(dān)保的團(tuán)隊(duì),也就可以在一定程度上簡(jiǎn)化沙箱對(duì)這段代碼實(shí)施的限制。
可以對(duì)由不同團(tuán)體簽名的代碼建立不同的安全限制。
要對(duì)一段代碼作擔(dān)保或簽名,必須首先生成一個(gè)公鑰/私鑰對(duì)。用戶保管私鑰,把公鑰公開。
至少,應(yīng)該把公鑰給那些要在你的簽名上建立安全策略的人。?
一旦擁有了一個(gè)公鑰/私鑰對(duì),就必須要簽名class文件和其他文件放到一個(gè)jar文件中,然后使用一個(gè)工具對(duì)整個(gè)jar文件簽名。
簽名工具將首先對(duì)jar文件的內(nèi)容進(jìn)行單向散列計(jì)算,以產(chǎn)生一個(gè)散列。
然后簽名工具將用私鑰對(duì)這個(gè)散列進(jìn)行簽名,并且將經(jīng)過簽名后的散列加到j(luò)ar文件的末尾。
這個(gè)簽名后的散列代表了你對(duì)這個(gè)jar文件內(nèi)容的數(shù)字簽名。
當(dāng)發(fā)布這個(gè)包含簽名散列的jar文件時(shí),那些持有你的公鑰的人將對(duì)jar文件驗(yàn)證兩件事:
這個(gè)jar文件確實(shí)是你簽名的,并且在你簽名后這個(gè)jar文件沒有做過任何改動(dòng)。
數(shù)字簽名過程的第一步 是一個(gè)單向的散列計(jì)算,它輸入大量的數(shù)據(jù),但產(chǎn)生少量的數(shù)據(jù),成為散列。
在這個(gè)jar文件的例子中,這個(gè)計(jì)算的大量輸入就是組成這個(gè)jar文件內(nèi)容的字節(jié)流。
這個(gè)單向散列計(jì)算是“單向”,在只給出散列的情況下,這個(gè)散列值不能包含足夠的輸入的信息,因此不能從散列重新生成原輸入。
這個(gè)計(jì)算是單向的,從大到小,從輸入到散列。
散列也被成為消息文摘,它相當(dāng)于一種輸入“指紋”。
雖然不同的輸入可能會(huì)產(chǎn)生相同的散列,但實(shí)際情況下,一個(gè)散列足矣代表了產(chǎn)生它的輸入。
一個(gè)散列也被用于識(shí)別單向散列算法產(chǎn)生這個(gè)散列的輸入。
在認(rèn)證過程中,散列被用于驗(yàn)證某個(gè)輸入是否和產(chǎn)生這個(gè)原始散列的輸入相同,驗(yàn)證這個(gè)輸入在到達(dá)目的地途中有沒有被改動(dòng)。
因?yàn)椴豢赡軆H僅用散列重構(gòu)原輸入,一個(gè)散列僅在可以得到原輸入時(shí)才有用,因此,必須將輸入和散列一起傳輸。
對(duì)它們本身來說,輸入和散列的組合并不安全,為了防止這種情況的發(fā)生,就必須在發(fā)生散列前,用私鑰對(duì)它進(jìn)行加密。
只加密散列而不是對(duì)整個(gè)jar進(jìn)行加密,這是因?yàn)橛盟借€進(jìn)行加密是一個(gè)相當(dāng)費(fèi)事的過程,一般來說,從jar文件中計(jì)算、產(chǎn)生一個(gè)單向散列,并對(duì)這個(gè)散列用私鑰進(jìn)行加密,要比對(duì)整個(gè)jar文件用私鑰進(jìn)行加密來得快。
只有當(dāng)黑客擁有你的私鑰時(shí),才能同時(shí)替換輸入和加密后的散列,因此要小心保存私鑰。
任何用你的私鑰加密的東西 都可以用你的公鑰解密。
公鑰/私鑰對(duì)具有這種特點(diǎn),在僅給出公鑰的情況下,想要產(chǎn)生私鑰是非常困難的。
因?yàn)閱蜗蛏⒘兴惴ㄊ菑拇罅繑?shù)據(jù)(輸入)中產(chǎn)生少量數(shù)據(jù)(消息摘要或者散列),所以不同的輸入可能產(chǎn)生相同的散列。
實(shí)際情況中,普遍采用的是64位或者128位的散列,通常認(rèn)為這個(gè)長(zhǎng)度已經(jīng)足夠了。
在產(chǎn)生散列值并用私鑰對(duì)它簽名后,隨后將加密后的散列值加到同一個(gè)jar文件中,這個(gè)jar還包含了最初產(chǎn)生這個(gè)散列 的文件。
一個(gè)經(jīng)簽名的jar文件,包含了輸入---你要擔(dān)保的class文件和數(shù)據(jù)文件---以及用你的私鑰加密過的散列值(由輸入產(chǎn)生)。
加密的散列代表了你對(duì)同一個(gè)jar文件中的類和數(shù)據(jù)文件的數(shù)字簽名,
要認(rèn)證一個(gè)已簽名的jar文件,接受者必須用公鑰對(duì)簽名散列進(jìn)行解密,得到的結(jié)果應(yīng)該和從jar文件計(jì)算而得到的散列值相等。
為了驗(yàn)證一個(gè)jar文件在簽名后未被改動(dòng),接受者只要對(duì)jar文件的內(nèi)容實(shí)施單向散列算法,就像在簽名過程中所作的那樣。
如果得到的散列值和加密的散列值匹配,那么接受者就可以推斷,你確實(shí)為jar文件進(jìn)行了擔(dān)保,而且這個(gè)jar文件的內(nèi)容在你加上你的簽名后沒有被改動(dòng)過。這個(gè)jar文件中包含的代碼就可以被放在一個(gè)不嚴(yán)格的沙箱中,這個(gè)沙箱信任你的簽名。
證書機(jī)構(gòu)將用證書機(jī)構(gòu)的私鑰對(duì)某些人的公鑰進(jìn)行簽名,最終得到的數(shù)字序列被稱為證書。