文章目錄
JAR 檔案可以用 jarsigner 工具或者直接通過 java.security API 簽名。一個簽名的 JAR 檔案與原來的 JAR 檔案完全相同,只是更新了它的 manifest,並在 META-INF 目錄中增加了兩個檔案,一個簽名檔案和一個簽名塊檔案。
JAR 檔案是用一個儲存在 Keystore 資料庫中的認證簽名的。儲存在 keystore 中的認證有密碼保護,必須向 jarsigner 工具提供這個密碼才能對 JAR 檔案簽名。
JAR 的每一位簽名者都由在 JAR 檔案的 META-INF 目錄中的一個具有 .SF 副檔名的簽名檔案表示。這個檔案的格式類似於 manifest 檔案 -- 一組 RFC-822 頭。如下所示,它的組成包括一個主要部分,它包括了由簽名者提供的資訊、但是不特別針對任何特定的 JAR 檔案項,還有一系列的單獨的項,這些項也必須包含在 menifest 檔案中。在驗證一個簽名的 JAR 時,將簽名檔案的摘要值與對 JAR 檔案中的相應項計算的摘要值進行比較。
Contents of signature file META-INF/MANIFEST.MFManifest-Version: 1.0Created-By: 1.3.0 (Sun Microsystems Inc.)Name: Sample.javaSHA1-Digest: 3+DdYW8INICtyG8ZarHlFxX0W6g=Name: Sample.classSHA1-Digest: YJ5yQHBZBJ3SsTNcHJFqUkfWEmI=Contents of signature file META-INF/JAMES.SFSignature-Version: 1.0SHA1-Digest-Manifest: HBstZOJBuuTJ6QMIdB90T8sjaOM=Created-By: 1.3.0 (Sun Microsystems Inc.)Name: Sample.javaSHA1-Digest: qipMDrkurQcKwnyIlI3Jtrnia8Q=Name: Sample.classSHA1-Digest: pT2DYby8QXPcCzv2NwpLxd8p4G4=
|
一個數位簽章是.SF 簽名檔案的已簽名版本。數位簽章檔案是二進位檔案,並且與 .SF 檔案有相同的檔案名稱,但是副檔名不同。根據數位簽章的類型 -- RSA、DSA 或者 PGP -- 以及用於簽名 JAR 的認證類型而有不同的副檔名。
要簽名一個 JAR 檔案,必須首先有一個私密金鑰。私密金鑰及其相關的密鑰憑證儲存在名為 keystores 的、有密碼保護的資料庫中。JDK 包含建立和修改 keystores 的工具。keystore 中的每一個密鑰都可以用一個別名標識,它通常是擁有這個密鑰的簽名者的名字。
所有 keystore 項(密鑰和信任的認證項)都是用唯一別名訪問的。別名是在用 keytool -genkey 命令產生金鑰組(公開金鑰和私密金鑰)並在 keystore 中添加項時指定的。之後的 keytool 命令必須使用同樣的別名引用這一項。
例如,要用別名“james”產生一個新的公開金鑰/私密金鑰對並將公開金鑰封裝到自簽名的認證中,要使用下述命令:
keytool -genkey -alias james -keypass jamespass -validity 80 -keystore jamesKeyStore -storepass jamesKeyStorePass
|
這個命令序列指定了一個初始密碼“jamespass”,後續的命令在訪問 keystore “jamesKeyStore”中與別名“james”相關聯的私密金鑰時,就需要這個密碼。如果 keystore“jamesKeyStore”不存在,則 keytool 會自動建立它。
jarsigner 工具使用 keystore 產生或者驗證 JAR 檔案的數位簽章。
假設像上述例子那樣建立了 keystore “jamesKeyStore”,並且它包含一個別名為“james”的密鑰,可以用下面的命令簽名一個 JAR 檔案:
jarsigner -keystore jamesKeyStore -storepass jamesKeyStorePass -keypass jamespass -signedjar SSample.jar Sample.jar james
|
這個命令用密碼“jamesKeyStorePass”從名為“jamesKeyStore”的 keystore 中提出別名為“james”、密碼為“jamespass”的密鑰,並對 Sample.jar 檔案簽名、建立一個簽名的 JAR -- SSample.jar。
jarsigner 工具還可以驗證一個簽名的 JAR 檔案,這種操作比簽名 JAR 檔案要簡單得多,只需執行以下命令:
jarsigner -verify SSample.jar
|
如果簽名的 JAR 檔案沒有被篡改過,那麼 jarsigner 工具就會告訴您 JAR 通過驗證了。否則,它會拋出一個 SecurityException , 表明哪些檔案沒有通過驗證。
還可以用 java.util.jar 和 java.security API 以編程方式簽名 JAR(有關細節參閱 參考資料)。也可以使用像 Netscape Object Signing Tool 這樣的工具。
將已簽名的Jar包清理,重新簽名
1. resign.sh script (strips key, adds key, add index)#!/bin/sh
# $Id: resign.sh,v 1.3 2002/07/02 13:57:32 mvw Exp $
# This script resigns the jars
# (remove old signature, add new signature)
# settings for present foo server
JDK=/usr/java/j2sdk1.4.0
KEYSTORE=../../Frontend/webstart/key/fooKeystore
. ./files.sh
for i in $unsigned_files
do
echo "---"
echo "unpacking $i .."
TMP=tmp-$i
mkdir $TMP
cd $TMP
unzip -q ../$i
chmod -R u+rwx *
find . -type f | xargs chmod u-x
echo "changing META-INF stuff .."
cd META-INF
rm -f *.SF
rm -f *.DSA
# this will determine the line number of the first blank line in MANIFEST.MF
# (a blank line here is anything that has no letter/number)
CUT=`egrep -nv '^.*[a-z|A-Z|0-9]+.*$' MANIFEST.MF|sed s/://|head -1|tr -d " "`
if [ -z "$CUT" ];
then
echo "no cut detected";
else
echo "cutting MANIFEST.MF at line $CUT .." &&
head -$CUT MANIFEST.MF >m.mf &&
rm -f MANIFEST.MF &&
mv m.mf MANIFEST.MF &&
cat MANIFEST.MF;
fi
echo "repacking $i .."
cd ..
rm -f ../$i
zip -q9r ../$i .
cd ..
rm -rf $TMP
echo "signing $i .."
$JDK/bin/jarsigner -keystore $KEYSTORE -storepass foopassword $i fookeyname
echo "verifying the signatures of $i .."
$JDK/bin/jarsigner -verify $i
echo indexing $i ..
$JDK/bin/jar -i $i
done
2. files.sh (a list of files to treat)
# $Id: files.sh,v 1.1 2002/05/07 16:35:18 mvw Exp $
# Files list
# watch out for
# - the double quotes,
# - the trailing space inside the quoted string,
# - the backslash immediatly following the closing quote
unsigned_files=
"foo1.jar "
"foo2.jar "
"foo3.jar "
"foo-help.jar "
[code]原貼見:
http://blog.csdn.net/hunterK/archive/2006/09/06/1186742.aspx