JAR文件签名
可以使用jarsigner命令或java.security API对JAR文件进行签名。一旦对JAR文件进行签名,那么JAR文件中每个文件都将被签名,并且在META-INF目录下生成*.SF、.DSA、.RSA或SIG-*文件(不同类型的数字签名生成不同扩展名的签名块文件DSA/RSA)。
签名之后的JAR文件与原来的JAR文件完全相同,只是更新了MANIFEST.MF文件和在META-INF目录增加签名文件和签名块文件。
*.SF:JAR文件的签名文件。
*.DSA:与签名文件关联的签名块文件,该文件存储相应签名文件的数字签名。
.SF文件的格式类似于MANIFEST.MF文件格式。
.MF文件
Signature-Version: 1.0
SHA-256-Digest-Manifest-Main-Attributes: nVH5+UfnoVN7VZD5nXddPLk/uoPMM
lN+jgQGIMIMmYo=
SHA-256-Digest-Manifest: KEROFj64PWEfzqny6f0gM79k6JlUq/ZxVUFpNBAgBKw=
Created-By: 1.8.0_151 (Oracle Corporation)
Name: Test.class
SHA-256-Digest: kLzf2IRRVshRgpU64hriBtFE/ZEqU9tcvzatqqViktE=
- x-Digest-Manifest-Main-Attributes(其中x是java.security.MessageDigest算法的标准名称):此属性的值是Manifest主要属性的Digest值。
- x-Digest-Manifest(其中x是java.security.MessageDigest算法的标准名称):此属性的值是整个Manifest的Digest值。
MANIFEST.MF文件
Manifest-Version: 1.0
Sealed: true
Created-By: 1.8.0_151 (Oracle Corporation)
Main-Class: Test
Name: Test.class
SHA-256-Digest: aGUNUPQVlMdD47vPnPDDED9cXCVgE2tZADE+R7WkDH0=
Keystore
JAR文件使用存储在Keystore数据库中的证书来签名。存储在keystore 中的证书有密码保护,必须向jarsigner工具提供这个密码才能对JAR文件签名。
想要对JAR文件进行签名,必须先在Keystore存储私钥和公钥证书(keystore是一个有密码保护的数据库)。keystore中的每一个密钥都可以使用别名来标识,别名通常为签名者的机构。
keytool -genkey -alias 别名 -keypass 密码 -validity 有效期 -keystore 仓库名 -storepass 仓库密码
举个说明
keytool -genkey -alias test -keypass t123456 -validity 80 -keystore teststore -storepass s123456
以上命令使用别名test生成一对新的公钥和私钥,并将其放到自签名证书中。
jarsigner 工具
jarsigner工具使用keystore中密钥对JAR文件进行签名或者验证JAR文件的数字签名。
签名
jarsigner -keystore teststore -storepass s123456 -keypass t123456 -signedjar SignTest.jar Test.jar test
s123456从名为teststore的keystore中提出别名为test、密码为t123456的密钥,对Test.jar文件进行签名且在签名后创建SignTest.jar。
验证
jarsigner -verify SignTest.jar
如果签名的JAR文件没有被篡改过,使用jarsigner -verify命令会验证通过。否则,会抛出 SecurityException异常,同时列出哪些文件没有通过验证。
注:还可以用java.util.jar和java.security API以编程方式签名JAR.
JAR文件验证的步骤
1、首次解析META-INF.MF时验证签名文件(.SF)上的签名。请注意,此验证仅验证签名本身,而不验证JAR中被签名的文件。
2、如果.SF签名文件存在属性x-Digest-Manifest,根据在META-INF.MF上计算的Digest验证该值。如果.SF签名文件存在多个x-Digest-Manifest属性,必须至少有一个属性与计算的Digest值匹配。
3、如果.SF签名文件中不存在属性x-Digest-Manifest,或者上一步骤中计算的Digest值都不匹配,则执行以下验证:
x-Digest-Manifest-Main-Attributes属性,根据在META-INF.MF上计算的Digest验证该值。如果此计算失败,则JAR文件验证失败。
3.2、根据在META-INF.MF上计算的Digest验证签名文件中每个源文件信息部分中的Digest值。只要有Digest值不匹配,JAR文件就验证失败。