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文件就验证失败。