The jarsigner Command

名称

jarsigner - 签名和验证Java存档(JAR)文件

概要

jarsigner [选项] jar-文件 别名

jarsigner -verify [选项] jar-文件 [别名 ...]

jarsigner -version

选项
命令行选项。请参阅 jarsigner选项
-verify

-verify 选项可以在JAR文件名后面接受零个或多个密钥库别名。当指定 -verify 选项时,jarsigner 命令会检查用于验证JAR文件中每个已签名条目的证书是否与密钥库别名之一匹配。这些别名在由 -keystore 指定的密钥库或默认密钥库中定义。

如果您还指定了 -strict 选项,并且 jarsigner 命令检测到严重警告,则会显示消息“jar verified, with signer errors”。

jar-文件

-strict 选项,并且 jarsigner 命令检测到严重警告,则会显示消息“jar signed, with signer errors”。

别名
这些别名在由 -keystore 指定的密钥库或默认密钥库中定义。
-version
-version 选项打印 jarsigner 的程序版本。

描述

jarsigner 工具有两个目的:

JAR功能使得将类文件、图像、声音和其他数字数据打包到单个文件中以便更快更容易地分发成为可能。一个名为 jar 的工具使开发人员能够生成JAR文件。(从技术上讲,任何ZIP文件也可以被视为JAR文件,尽管当由 jar 命令创建或由 jarsigner 命令处理时,JAR文件还包含一个 META-INF/MANIFEST.MF 文件。)

数字签名是从某些数据(被签名的数据)和实体(个人、公司等)的私钥计算出的一串比特。类似于手写签名,数字签名具有许多有用的特性:

jarsigner 命令使用密钥库中的密钥和证书信息为JAR文件生成数字签名。密钥库是私钥及其关联的X.509证书链的数据库,用于验证相应公钥的身份。使用 keytool 命令来创建和管理密钥库。

jarsigner 命令使用实体的私钥生成签名。已签名的JAR文件包含了来自密钥库的证书副本,用于与用于签署文件的私钥对应的公钥的验证。jarsigner 命令可以使用签名块文件中的证书验证已签名JAR文件的数字签名。

jarsigner 命令可以生成包含时间戳的签名,使系统或部署者能够检查JAR文件是否在签名证书仍然有效时签名。

此外,API允许应用程序获取时间戳信息。

jarsigner 命令只能签署由 jar 命令或zip文件创建的JAR文件。JAR文件与zip文件相同,只是它们还包含一个 META-INF/MANIFEST.MF 文件。当 jarsigner 命令签署zip文件时,会创建一个 META-INF/MANIFEST.MF 文件。

jarsigner 命令行为是对JAR或zip文件进行签名。使用 -verify 选项来验证已签名的JAR文件。

jarsigner 命令还尝试验证签名者的证书。在验证期间,当指定 -revCheck 选项时,它会检查签名者证书链中每个证书的吊销状态。如果存在验证错误或任何其他问题,命令会生成警告消息。如果指定了 -strict 选项,则命令将严重警告视为错误。请参阅 错误和警告

密钥库别名

jarsigner 命令对JAR文件进行签名时,必须指定包含生成签名所需的私钥的密钥库条目的别名。如果未指定输出文件,则会用签名后的JAR文件覆盖原始JAR文件。

密钥库位置

jarsigner 命令有一个 -keystore 选项,用于指定要使用的密钥库的URL。密钥库默认存储在名为 .keystore 的文件中,该文件位于用户的主目录中,由 user.home 系统属性确定。

Linux 和 macOS: user.home 默认为用户的主目录。

-keystore 选项的输入流传递给 KeyStore.load 方法。如果指定 NONE 作为URL,则会将空流传递给 KeyStore.load 方法。当 KeyStore 类不是基于文件时,例如当它位于硬件令牌设备上时,应指定 NONE

密钥库实现

java.security 包中提供的 KeyStore 类提供了一些明确定义的接口,用于访问和修改密钥库中的信息。您可以拥有多个不同的具体实现,其中每个实现都是针对特定类型的密钥库。

keytooljarsigner)。

PKCS12。这是基于RSA PKCS12个人信息交换语法标准的跨平台密钥库。该标准主要用于存储或传输用户的私钥、证书和其他杂项机密。还有另一个由Oracle提供的内置实现。它将密钥库实现为具有专有密钥库类型(格式)的文件,名为 JKS。它使用各自的密码保护每个私钥,并使用(可能不同的)密码保护整个密钥库的完整性。

KeyStore 类提供的应用程序接口是基于服务提供程序接口(SPI)实现的。还有一个对应的抽象 KeystoreSpi 类,也在 java.security 包中,定义了提供程序必须实现的服务提供程序接口方法。提供程序是指提供Java安全API可以访问的一组服务子集的包或一组包。要提供密钥库实现,客户端必须实现一个提供程序并提供一个 KeystoreSpi 子类实现,如 如何在Java加密体系结构中实现提供程序 中所述。

KeyStore 类中的 getInstance 工厂方法从不同提供程序中选择不同类型的密钥库实现。密钥库类型定义了密钥库信息的存储和数据格式以及用于保护密钥库中的私钥和密钥库本身完整性的算法。不同类型的密钥库实现不兼容。

jarsigner 命令可以从可以使用URL指定的任何位置读取基于文件的密钥库。此外,这些命令可以读取非基于文件的密钥库,例如Windows上提供的MSCAPI和所有平台上提供的PKCS11。

jarsignerkeytool 命令,您可以使用 -storetype 选项在命令行中指定密钥库类型。

keystore.type 属性的值选择密钥库实现。安全属性文件称为 java.security,位于JDK安全属性目录 java.home/conf/security 中。

keystore.type 值,然后检查所有已安装的提供程序,直到找到一个实现该类型密钥库的提供程序。然后使用该提供程序的密钥库实现。

KeyStore 类定义了一个名为 getDefaultType 的静态方法,允许应用程序检索 keystore.type 属性的值。以下代码行创建指定的默认密钥库类型的实例,如 keystore.type 属性中指定的:

KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());

pkcs12,这是基于RSA PKCS12个人信息交换语法标准的跨平台密钥库。在安全属性文件中的以下行指定了此值:

keystore.type=pkcs12

JKSjks 相同。

jks 密钥库实现,则将该行更改为以下内容:

keystore.type=jks

支持的算法

默认情况下,jarsigner 命令使用以下算法之一对 JAR 文件进行签名,并根据私钥的类型和大小使用不同的块文件扩展名:

默认签名算法和块文件扩展名
keyalg keysize 默认 sigalg 块文件扩展名
DSA 任意大小 SHA256withDSA .DSA
RSA < 624 SHA256withRSA .RSA
<= 7680 SHA384withRSA
> 7680 SHA512withRSA
EC < 512 SHA384withECDSA .EC
>= 512 SHA512withECDSA
RSASSA-PSS < 624 RSASSA-PSS(使用 SHA-256) .RSA
<= 7680 RSASSA-PSS(使用 SHA-384)
> 7680 RSASSA-PSS(使用 SHA-512)
EdDSA 255 Ed25519 .EC
448 Ed448
  • 如果 RSASSA-PSS 密钥使用参数编码,则 jarsigner 将在签名中使用相同的参数。否则,jarsigner 将使用由密钥大小在上表中指定的参数。例如,一个 3072 位的 RSASSA-PSS 密钥将使用 RSASSA-PSS 作为签名算法,SHA-384 作为哈希算法和 MGF1 算法。

可以通过使用 -sigalg 选项来覆盖这些默认签名算法。

jarsigner 命令使用 jdk.jar.disabledAlgorithmsjdk.security.legacyAlgorithms 安全属性来确定哪些算法被视为安全风险。如果 JAR 文件使用了任何已禁用的算法进行签名,它将被视为未签名的 JAR 文件。如果 JAR 文件使用了任何遗留算法进行签名,它将被视为使用了信息性警告进行签名,以通知用户该遗留算法将在未来更新中被禁用。要获取详细的验证输出,请包括 -J-Djava.security.debug=jarjdk.jar.disabledAlgorithmsjdk.security.legacyAlgorithms 安全属性在 java.security 文件中定义(位于 JDK 的 $JAVA_HOME/conf/security 目录中)。

注意:

为了提高开箱即用的安全性,每个 JDK 版本的默认密钥大小和签名算法名称都会定期更新为更强大的值。如果与旧版本的 JDK 进行互操作性很重要,请确保这些默认值受到这些版本支持,或者可以使用 -sigalg 选项自行覆盖默认值,但需自担风险。

已签名的 JAR 文件

当使用 jarsigner 命令对 JAR 文件进行签名时,输出的已签名 JAR 文件与输入的 JAR 文件完全相同,只是在 META-INF 目录中多了两个附加文件:

  • 带有 .SF 扩展名的签名文件

  • 带有 .DSA.RSA.EC 扩展名的签名块文件

这两个文件的基本文件名来自 -sigfile 选项的值。例如,当选项为 -sigfile MKSIGN 时,文件名为 MKSIGN.SFMKSIGN.RSA。在本文档中,我们假设签名者始终使用 RSA 密钥。

如果命令行中没有出现 -sigfile 选项,则 .SF 和签名块文件的基本文件名是命令行上指定的别名的前 8 个字符,全部转换为大写。如果别名少于 8 个字符,则使用完整别名。如果别名包含任何不允许在签名文件名中的字符,则在形成文件名时将每个此类字符转换为下划线 (_) 字符。有效字符包括字母、数字、下划线和连字符。

签名文件

签名文件(.SF 文件)看起来类似于始终在使用 jarsigner 命令对文件进行签名时包含的清单文件。对于 JAR 文件中包含的每个源文件,.SF 文件有两行,就像在清单文件中一样,列出了以下内容:

  • 文件名

  • 摘要算法的名称(SHA)

  • SHA 摘要值

注意:

摘要算法的名称(SHA)和 SHA 摘要值在同一行上。

在清单文件中,每个源文件的 SHA 摘要值是源文件中的二进制数据的摘要(哈希)。在 .SF 文件中,指定源文件的摘要值是清单文件中该源文件的两行的哈希。

默认情况下,签名文件包含一个头部,其中包含整个清单文件的哈希。头部还包含清单头部的哈希。头部的存在使得验证优化。请参见 JAR 文件验证

签名块文件

.SF 文件被签名,并将签名放置在签名块文件中。该文件还包含了从密钥库中的证书或证书链中编码的用于验证与用于签名的私钥对应的公钥的证书。该文件的扩展名为 .DSA.RSA.EC,取决于所使用的密钥算法。请参见 支持的算法 中的表格。

签名时间戳

使用以下选项运行的 jarsigner 命令在签署 JAR 文件时生成并存储签名时间戳:

  • -tsa url

  • -tsacert alias

  • -tsapolicyid policyid

  • -tsadigestalg algorithm

请参见 jarsigner 的选项

JAR 文件验证

成功的 JAR 文件验证发生在签名有效且在生成签名时 JAR 文件中的任何文件自那时起未发生更改的情况下。JAR 文件验证包括以下步骤:

  1. 验证 .SF 文件的签名。

    此验证确保存储在每个签名块文件中的签名是使用与签名块文件中的公钥对应的私钥生成的。它还确保签名是相应签名(.SF)文件的有效签名,因此 .SF 文件没有被篡改。

  2. 验证 .SF 文件中每个条目中列出的摘要与清单中每个相应部分的摘要。

    .SF 文件默认包含一个头部,其中包含整个清单文件的哈希。当头部存在时,验证可以检查头部的哈希是否与清单文件的哈希匹配。如果匹配,则验证继续进行下一步。

    如果没有匹配,则需要进行较少优化的验证,以确保 .SF 文件中每个源文件信息部分中的哈希等于清单文件中相应部分的哈希。请参见签名文件。

    存储在 .SF 文件头部中的清单文件的哈希可能与当前清单文件的哈希不匹配的一个原因是,它可能包含在文件签名后添加的新文件的部分。例如,假设一个或多个文件被添加到已签名的 JAR 文件(使用 jar 工具),该文件已包含签名和 .SF 文件。如果 JAR 文件由不同的签名者再次签名,则清单文件会更改(jarsigner 工具会为新文件添加部分),并创建一个新的 .SF 文件,但原始的 .SF 文件保持不变。如果自原始签名生成 JAR 文件后未更改任何文件,则仍将视为验证成功。这是因为 .SF 文件的非头部部分中的哈希等于清单文件中相应部分的哈希。

  3. 读取 JAR 文件中具有 .SF 文件条目的每个文件。在读取时,计算文件的摘要并将结果与清单部分中此文件的摘要进行比较。摘要应该相同,否则验证失败。

    如果在验证过程中发生任何严重的验证失败,则进程将停止并抛出安全异常。 jarsigner 命令会捕获并显示异常。

  4. 检查禁用算法的使用。请参见 支持的算法

注意:

您应该阅读任何额外警告(或如果指定了 -strict 选项,则为错误),以及证书的内容(通过指定 -verbose-certs 选项)以确定签名是否可信。

JAR 文件的多个签名

可以通过多次对文件运行 jarsigner 命令并每次指定不同人员的别名来由多人对 JAR 文件进行签名,如下所示:

jarsigner myBundle.jar susan
jarsigner myBundle.jar kevin

当一个JAR文件被多次签名时,在生成的JAR文件中会有多个.SF和签名块文件,每个签名对应一个文件对。在上面的例子中,输出的JAR文件包括以下文件:

SUSAN.SF
SUSAN.RSA
KEVIN.SF
KEVIN.RSA

jarsigner的选项

以下部分描述了jarsigner的选项。请注意以下标准:

  • 所有选项名称前面都有一个连字符(-)。

  • 选项可以以任何顺序提供。

  • 斜体或下划线的项目(选项值)代表必须提供的实际值。

  • 当签署JAR文件时,-storepass-keypass-sigfile-sigalg-digestalg-signedjar和TSA相关选项仅相关;在验证签名的JAR文件时,它们不相关。-keystore选项在签署和验证JAR文件时都相关。此外,在签署和验证JAR文件时指定别名。

-keystore url

指定包含密钥库位置的URL。默认情况下,密钥库文件为用户主目录中的.keystore文件,由user.home系统属性确定。

签名时需要密钥库。当默认密钥库不存在或者想要使用其他密钥库时,必须显式指定一个密钥库。

验证时不需要密钥库,但如果指定了一个或者默认密钥库存在且还指定了-verbose选项,则会输出关于用于验证JAR文件的证书是否包含在该密钥库中的额外信息。

-keystore参数可以是文件名和路径规范,而不是URL,此时它被视为文件URL,例如,以下两种方式是等效的:

  • -keystore 文件路径和名称

  • -keystore file:文件路径和名称

如果在java.security安全属性文件(位于JDK的$JAVA_HOME/conf/security目录中)中配置了Sun PKCS#11提供程序,则可以通过指定以下选项使keytooljarsigner工具操作PKCS#11令牌:

-keystore NONE -storetype PKCS11

例如,以下命令列出了配置的PKCS#11令牌的内容:

keytool -keystore NONE -storetype PKCS11 -list

-storepass [:env | :file] 参数

指定访问密钥库所需的密码。只有在签名(而不是验证)JAR文件时才需要。在这种情况下,如果命令行中没有提供-storepass选项,则会提示用户输入密码。

如果未指定修饰符envfile,则密码的值为参数。否则,密码将按以下方式检索:

  • env:从名为参数的环境变量中检索密码。

  • file:从名为参数的文件中检索密码。

注意:

除非用于测试目的或者在安全系统上,否则不应在命令行或脚本中指定密码。

-storetype 存储类型

指定要实例化的密钥库类型。默认密钥库类型是安全属性文件中keystore.type属性的值,该值由java.security.KeyStore中的静态getDefaultType方法返回。

PKCS#11令牌的PIN也可以通过-storepass选项指定。如果未指定PIN,则keytooljarsigner命令会提示输入令牌PIN。如果令牌具有受保护的身份验证路径(例如专用PIN键盘或生物识别读卡器),则必须指定-protected选项,不能指定密码选项。

-keypass [:env | :file] 参数 -certchain 文件

指定用于保护由命令行上指定的别名对应的密钥库条目的私钥的密码。在使用jarsigner签署JAR文件时需要密码。如果命令行中未提供密码,并且所需密码与存储密码不同,则会提示用户输入密码。

如果未指定修饰符envfile,则密码的值为参数。否则,密码将按以下方式检索:

  • env:从名为参数的环境变量中检索密码。

  • file:从名为参数的文件中检索密码。

注意:

除非用于测试目的或者在安全系统上,否则不应在命令行或脚本中指定密码。

-certchain 文件
指定在命令行上指定的别名对应的密钥库条目的私钥的证书链在没有完整证书链的情况下使用。当密钥库位于容量不足以容纳完整证书链的硬件令牌上时,可能会发生这种情况。该文件可以是一系列连接的X.509证书,也可以是单个PKCS#7格式的数据块,可以是二进制编码格式或可打印编码格式(也称为Base64编码),由Internet RFC 1421证书编码标准定义。
-sigfile 文件

指定用于生成.SF和签名块文件的基本文件名。例如,如果文件为DUKESIGN,则生成的.SF和签名块文件名为DUKESIGN.SFDUKESIGN.RSA,并放置在已签名JAR文件的META-INF目录中。

文件中的字符必须来自集合a-zA-Z0-9_-。只允许字母、数字、下划线和连字符字符。所有小写字符都会转换为大写用于.SF和签名块文件名。

如果命令行中没有-sigfile选项,则.SF和签名块文件的基本文件名是命令行上指定的别名的前8个字符,全部转换为大写。如果别名少于8个字符,则使用完整别名。如果别名包含任何不符合签名文件名的字符,则将每个此类字符转换为下划线(_)字符以形成文件名。

-signedjar 文件
指定已签名JAR文件的名称。
-digestalg 算法

指定在摘要JAR文件条目时使用的消息摘要算法的名称。

有关标准消息摘要算法名称列表,请参阅Java安全标准算法名称。

如果未指定此选项,则使用SHA-384。必须有一个静态安装的提供程序提供指定算法的实现,或者用户必须使用-addprovider-providerClass选项指定一个;否则,命令将无法成功执行。

-sigalg 算法

指定用于签署JAR文件的签名算法的名称。

此算法必须与用于签署JAR文件的私钥兼容。如果未指定此选项,则使用与私钥匹配的默认算法,如支持的算法部分所述。必须有一个静态安装的提供程序提供指定算法的实现,或者必须使用-addprovider-providerClass选项指定一个;否则,命令将无法成功执行。

有关标准消息摘要算法名称列表,请参阅Java安全标准算法名称。

-verify
验证已签名的JAR文件。
-verbose[:子选项]

当命令行中出现-verbose选项时,表示jarsigner在签署或验证时使用详细模式,子选项确定显示多少信息。这会导致jarsigner输出有关JAR签署或验证进度的额外信息。子选项可以是allgroupedsummary

如果还指定了-certs选项,则默认模式(或子选项all)会显示正在处理的每个条目,然后显示JAR文件每个签名者的证书信息。

如果指定了-certs-verbose:grouped子选项,则具有相同签名者信息的条目将被分组并与其证书信息一起显示。

如果指定了-certs-verbose:summary子选项,则具有相同签名者信息的条目将被分组并与其证书信息一起显示。

有关每个条目的详细信息将被汇总并显示为一个条目(及更多)。请参阅验证已签名JAR文件示例带证书信息的验证示例

-certs

如果命令行中出现-certs选项并且还有-verify-verbose选项,则输出将包括JAR文件每个签名者的证书信息。此信息包括证书类型的名称(存储在签名块文件中)以证明签名者的公钥,如果证书是X.509证书(java.security.cert.X509Certificate的实例),则显示签名者的可分辨名称。

还会检查密钥库。如果命令行中未指定密钥库值,则会检查默认密钥库文件(如果有)。如果签名者的公钥证书与密钥库中的条目匹配,则会在括号中显示该签名者的密钥库条目的别名。

-revCheck
此选项在签署或验证JAR文件时启用证书的吊销检查。如果命令行中指定了-revCheck选项,则jarsigner命令会尝试建立网络连接以获取OCSP响应和CRL。请注意,除非指定此选项,否则不会启用吊销检查。
-tsa url

如果在签署JAR文件时命令行中出现-tsa http://example.tsa.url,则会为签名生成时间戳。URL http://example.tsa.url标识时间戳机构(TSA)的位置,并覆盖-tsacert选项中找到的任何URL。-tsa选项不需要TSA公钥证书存在于密钥库中。

为了生成时间戳,jarsigner使用RFC 3161中定义的时间戳协议(TSP)与TSA通信。成功后,TSA返回的时间戳令牌将与签名一起存储在签名块文件中。

-tsacert 别名

当在签署JAR文件时命令行中出现-tsacert alias,将为签名生成时间戳。别名标识密钥库中有效的TSA公钥证书。将检查条目的证书,以查看是否包含包含标识TSA位置的URL的主题信息访问扩展。

在使用-tsacert选项时,TSA公钥证书必须存在于密钥库中。

-tsapolicyid policyid

指定要发送到TSA服务器的策略ID的对象标识符(OID)。如果未指定此选项,则不会发送任何策略ID,TSA服务器将选择默认策略ID。

对象标识符由X.696定义,这是ITU电信标准化部门(ITU-T)的标准。这些标识符通常是非负数字的以句点分隔的集合,例如1.2.3.4

-tsadigestalg algorithm

指定用于生成发送到TSA服务器的消息摘要的消息摘要算法。如果未指定此选项,将使用SHA-384。

请参阅支持的算法

有关标准消息摘要算法名称的列表,请参阅Java安全标准算法名称。

-internalsf
在过去,当签署JAR文件时生成签名块文件时,该文件还包括完整编码的生成的.SF文件(签名文件)的副本。这种行为已更改。为了减小输出JAR文件的总体大小,默认情况下签名块文件不再包含.SF文件的副本。如果命令行中出现-internalsf,则将使用旧行为。此选项对于测试很有用。实际上,不要使用-internalsf选项,因为它会产生更高的开销。
-sectionsonly

如果命令行中出现-sectionsonly选项,则在签署JAR文件时生成的.SF文件(签名文件)不包含包含整个清单文件哈希的头部。它仅包含与JAR文件中包含的每个单独源文件相关的信息和哈希值。请参阅签名文件。

默认情况下,此头部被添加为优化。当头部存在时,每当验证JAR文件时,验证可以首先检查头部中的哈希值是否与整个清单文件的哈希值匹配。当匹配时,验证继续进行下一步。当没有匹配时,需要执行较不优化的验证,即.SF文件中每个源文件信息部分的哈希值是否等于清单文件中相应部分的哈希值。请参阅JAR文件验证

-sectionsonly选项主要用于测试。除了用于测试之外,不应使用它,因为使用它会产生更高的开销。

-protected
值可以是truefalse。当必须通过受保护的身份验证路径(如专用PIN阅读器)指定密码时,请指定true
-providerName providerName

如果在java.security安全属性文件中配置了多个提供程序,则可以使用-providerName选项来定位特定提供程序实例。此选项的参数是提供程序的名称。

对于Oracle PKCS#11提供程序,providerName的格式为SunPKCS11-TokenName,其中TokenName是提供程序实例配置的名称后缀,如配置属性表中详细说明的那样。例如,以下命令列出了具有名称后缀SmartCardPKCS#11密钥库提供程序实例的内容:

jarsigner -keystore NONE -storetype PKCS11 -providerName SunPKCS11-SmartCard -list

-addprovider name [-providerArg arg]

通过名称(例如SunPKCS11)和可选配置参数添加安全提供程序。安全提供程序的值是在模块中定义的安全提供程序的名称。

-providerArg ConfigFilePath选项一起使用时,keytooljarsigner工具会动态安装提供程序,并使用ConfigFilePath作为令牌配置文件的路径。以下示例显示了在安全属性文件中未配置Oracle PKCS#11提供程序时列出PKCS#11密钥库的命令。

jarsigner -keystore NONE -storetype PKCS11 -addprovider SunPKCS11 -providerArg /mydir1/mydir2/token.config

-providerClass provider-class-name [-providerArg arg]

用于指定当安全提供程序未在java.security安全属性文件中列出时,加密服务提供程序的主类文件的名称。通过完全限定的类名和可选配置参数添加安全提供程序。

注意:

通过使用模块加载PKCS11的首选方法是使用模块。请参阅-addprovider

-providerPath classpath
用于为由-providerClass选项指定的提供程序指定类路径。多个路径应该由系统相关的路径分隔符字符分隔。
-Jjavaoption
将指定的javaoption字符串直接传递给Java解释器。jarsigner命令是解释器的包装器。此选项不应包含任何空格。它用于调整执行环境或内存使用。要查看可能的解释器选项列表,请在命令行上键入java -hjava -X
-strict
在签署或验证过程中,命令可能会发出警告消息。如果指定此选项,则工具的退出代码将反映此命令发现的严重警告消息。请参阅错误和警告
-conf url
指定预配置的选项文件。阅读有关支持的属性键的详细信息,请参阅keytool文档。支持的属性键包括"jarsigner.all"用于所有操作,"jarsigner.sign"用于签名,以及"jarsigner.verify"用于验证。不能在此文件中设置包括JAR文件名和别名名称在内的jarsigner参数。
-version
打印程序版本。

错误和警告

在签名或验证过程中,jarsigner命令可能会发出各种错误或警告。

如果失败,jarsigner命令将以代码1退出。如果没有失败,但存在一个或多个严重警告,当未指定-strict选项时,jarsigner命令将以代码0退出;当指定了-strict时,将以警告代码的OR值退出。如果只有信息性警告或没有任何警告,该命令总是以代码0退出。

例如,如果用于签署条目的证书已过期并且具有不允许其签署文件的KeyUsage扩展,当指定-strict选项时,jarsigner命令将以代码12(=4+8)退出。

注意:退出代码被重复使用,因为在Linux和macOS上只有0到255的值是合法的。

以下部分描述了jarsigner命令可能发出的错误和警告的名称、代码和描述。

失败

jarsigner命令失败的原因包括(但不限于)命令行解析错误、找不到用于签署JAR文件的密钥对,或签署的JAR验证失败。

失败
代码1。签名或验证失败。

严重警告

注意:

如果指定了-strict选项,严重警告将报告为错误。

jarsigner命令发出严重警告的原因包括用于签署JAR文件的证书存在错误或签署的JAR文件存在其他问题。

hasExpiredCert
代码4。此JAR包含其签署者证书已过期的条目。
hasExpiredTsaCert
代码4。时间戳已过期。
notYetValidCert
代码4。此JAR包含其签署者证书尚未生效的条目。
chainNotValidated
代码4。此JAR包含其证书链未经验证的条目。
tsaChainNotValidated
代码64。时间戳无效。
signerSelfSigned
代码4。此JAR包含其签署者证书为自签名的条目。
disabledAlg
代码4。使用的算法被视为安全风险并已禁用。
badKeyUsage
代码8。此JAR包含其签署者证书的KeyUsage扩展不允许代码签名的条目。
badExtendedKeyUsage
代码8。此JAR包含其签署者证书的ExtendedKeyUsage扩展不允许代码签名的条目。
badNetscapeCertType
代码8。此JAR包含其签署者证书的NetscapeCertType扩展不允许代码签名的条目。
hasUnsignedEntry
代码16。此JAR包含未经完整性检查的未签名条目。
notSignedByAlias
代码32。此JAR包含未由指定别名签名的已签名条目。
aliasNotInStore
代码32。此JAR包含未由此密钥库中别名签名的已签名条目。
tsaChainNotValidated
代码64。此JAR包含其TSA证书链无效的条目。

信息性警告

信息性警告包括那些不是错误但被视为不良实践的警告。它们没有代码。

extraAttributesDetected
在签署或验证JAR文件时检测到POSIX文件权限和/或符号链接属性。jarsigner工具会在新签名文件中保留这些属性,但会警告这些属性未经签名且未受签名保护。
hasExpiringCert
此JAR包含其签署者证书在六个月内到期的条目。
hasExpiringTsaCert
时间戳将在一年内于YYYY-MM-DD到期。
legacyAlg
使用的算法被视为安全风险但未被禁用。
noTimestamp
此JAR包含的签名不包括时间戳。没有时间戳,用户可能无法在签署者证书到期日期(YYYY-MM-DD)或任何未来吊销日期之后验证此JAR文件。

签署JAR文件的示例

使用以下命令使用名为jane的用户的私钥在名为mystore的密钥库中的working目录中签署bundle.jar并将签名后的JAR文件命名为sbundle.jar

jarsigner -keystore /working/mystore -storepass keystore_password -keypass private_key_password -signedjar sbundle.jar bundle.jar jane

在上一个命令中未指定-sigfile,因此生成的.SF和签名块文件将根据别名名称的默认名称放置在签名的JAR文件中。它们被命名为JANE.SFJANE.RSA

如果希望提示输入存储密码和私钥密码,则可以将上一个命令缩短为以下命令:

jarsigner -keystore /working/mystore -signedjar sbundle.jar bundle.jar jane

如果keystore是默认的keystore(位于您的主目录中的.keystore),则无需指定keystore,如下所示:

jarsigner -signedjar sbundle.jar bundle.jar jane

如果希望签名的JAR文件覆盖输入的JAR文件(bundle.jar),则无需指定-signedjar选项,如下所示:

jarsigner bundle.jar jane

验证已签名JAR文件的示例

要验证已签名的JAR文件以确保签名有效且JAR文件未被篡改,请使用以下命令之一:

jarsigner -verify ButtonDemo.jar

当验证成功时,将显示jar verified。否则,将显示错误消息。当使用-verbose选项时,您可以获得更多信息。以下是使用-verbose选项的jarsigner的示例用法:

jarsigner -verify -verbose ButtonDemo.jar

s       866 Tue Sep 12 20:08:48 EDT 2017 META-INF/MANIFEST.MF
        825 Tue Sep 12 20:08:48 EDT 2017 META-INF/ORACLE_C.SF
       7475 Tue Sep 12 20:08:48 EDT 2017 META-INF/ORACLE_C.RSA
          0 Tue Sep 12 20:07:54 EDT 2017 META-INF/
          0 Tue Sep 12 20:07:16 EDT 2017 components/
          0 Tue Sep 12 20:07:16 EDT 2017 components/images/
sm      523 Tue Sep 12 20:07:16 EDT 2017 components/ButtonDemo$1.class
sm     3440 Tue Sep 12 20:07:16 EDT 2017 components/ButtonDemo.class
sm     2346 Tue Sep 12 20:07:16 EDT 2017 components/ButtonDemo.jnlp
sm      172 Tue Sep 12 20:07:16 EDT 2017 components/images/left.gif
sm      235 Tue Sep 12 20:07:16 EDT 2017 components/images/middle.gif
sm      172 Tue Sep 12 20:07:16 EDT 2017 components/images/right.gif

  s = 签名已验证
  m = 条目在清单中列出
  k = 在密钥库中找到至少一个证书

- 由"CN="Oracle America, Inc.", OU=Software Engineering, O="Oracle America, Inc.", L=Redwood City, ST=California, C=US"签名
    摘要算法:SHA-256
    签名算法:SHA256withRSA,2048位密钥
  时间戳由"CN=Symantec Time Stamping Services Signer - G4, O=Symantec Corporation, C=US"于Tue Sep 12 20:08:49 UTC 2017时间戳
    时间戳摘要算法:SHA-1
    时间戳签名算法:SHA1withRSA,2048位密钥

jar verified。

签署者证书于2018-02-01到期。但是,JAR文件将在时间戳于2020-12-29到期之前有效。

带证书信息的验证示例

如果在-verify-verbose选项中指定了-certs选项,则输出将包括JAR文件每个签署者的证书信息。该信息包括证书类型、签署者的专有名称信息(当为X.509证书时),以及括号中的签署者的密钥库别名,当JAR文件中的公钥证书与密钥库条目中的证书匹配时,例如:

jarsigner -keystore $JAVA_HOME/lib/security/cacerts -verify -verbose -certs ButtonDemo.jar

s k     866 Tue Sep 12 20:08:48 EDT 2017 META-INF/MANIFEST.MF

      >>> 签名者
      X.509, CN="Oracle America, Inc.", OU=软件工程, O="Oracle America, Inc.", L=Redwood City, ST=加利福尼亚州, C=美国
      [证书有效期从2017-01-30, 7:00 PM 到 2018-02-01, 6:59 PM]
      X.509, CN=Symantec Class 3 SHA256 Code Signing CA, OU=Symantec Trust Network, O=Symantec Corporation, C=美国
      [证书有效期从2013-12-09, 7:00 PM 到 2023-12-09, 6:59 PM]
      X.509, CN=VeriSign Class 3 Public Primary Certification Authority - G5, OU="(c) 2006 VeriSign, Inc. - 仅限授权使用", OU=VeriSign Trust Network, O="VeriSign, Inc.", C=美国 (verisignclass3g5ca [jdk])
      [受信任的证书]
      >>> 时间戳授权机构
      X.509, CN=Symantec Time Stamping Services Signer - G4, O=Symantec Corporation, C=美国
      [证书有效期从2012-10-17, 8:00 PM 到 2020-12-29, 6:59 PM]
      X.509, CN=Symantec Time Stamping Services CA - G2, O=Symantec Corporation, C=美国
      [证书有效期从2012-12-20, 7:00 PM 到 2020-12-30, 6:59 PM]

        825 Tue Sep 12 20:08:48 EDT 2017 META-INF/ORACLE_C.SF
       7475 Tue Sep 12 20:08:48 EDT 2017 META-INF/ORACLE_C.RSA
          0 Tue Sep 12 20:07:54 EDT 2017 META-INF/
          0 Tue Sep 12 20:07:16 EDT 2017 components/
          0 Tue Sep 12 20:07:16 EDT 2017 components/images/
smk     523 Tue Sep 12 20:07:16 EDT 2017 components/ButtonDemo$1.class

      [条目于2017-09-12, 4:08 PM 签名]
      >>> 签名者
      X.509, CN="Oracle America, Inc.", OU=软件工程, O="Oracle America, Inc.", L=Redwood City, ST=加利福尼亚州, C=美国
      [证书有效期从2017-01-30, 7:00 PM 到 2018-02-01, 6:59 PM]
      X.509, CN=Symantec Class 3 SHA256 Code Signing CA, OU=Symantec Trust Network, O=Symantec Corporation, C=美国
      [证书有效期从2013-12-09, 7:00 PM 到 2023-12-09, 6:59 PM]
      X.509, CN=VeriSign Class 3 Public Primary Certification Authority - G5, OU="(c) 2006 VeriSign, Inc. - 仅限授权使用", OU=VeriSign Trust Network, O="VeriSign, Inc.", C=美国 (verisignclass3g5ca [jdk])
      [受信任的证书]
      >>> 时间戳授权机构
      X.509, CN=Symantec Time Stamping Services Signer - G4, O=Symantec Corporation, C=美国
      [证书有效期从2012-10-17, 8:00 PM 到 2020-12-29, 6:59 PM]
      X.509, CN=Symantec Time Stamping Services CA - G2, O=Symantec Corporation, C=美国
      [证书有效期从2012-12-20, 7:00 PM 到 2020-12-30, 6:59 PM]

smk    3440 Tue Sep 12 20:07:16 EDT 2017 components/ButtonDemo.class
...
smk    2346 Tue Sep 12 20:07:16 EDT 2017 components/ButtonDemo.jnlp
...
smk     172 Tue Sep 12 20:07:16 EDT 2017 components/images/left.gif
...
smk     235 Tue Sep 12 20:07:16 EDT 2017 components/images/middle.gif
...
smk     172 Tue Sep 12 20:07:16 EDT 2017 components/images/right.gif
...

  s = 签名已验证
  m = 条目在清单中列出
  k = 在密钥库中找到至少一个证书

- 由"CN="Oracle America, Inc.", OU=软件工程, O="Oracle America, Inc.", L=Redwood City, ST=加利福尼亚州, C=美国"签名
    摘要算法: SHA-256
    签名算法: SHA256withRSA, 2048位密钥
  由"CN=Symantec Time Stamping Services Signer - G4, O=Symantec Corporation, C=美国"于Tue Sep 12 20:08:49 UTC 2017时间戳
    时间戳摘要算法: SHA-1
    时间戳签名算法: SHA1withRSA, 2048位密钥

jar已验证。

签名者证书于2018-02-01过期。然而,JAR文件将在时间戳于2020-12-29过期之前有效。

如果签名者的证书不是X.509证书,则没有专有名称信息。在这种情况下,只显示证书类型和别名。例如,如果证书是PGP证书,别名是bob,则会显示为:PGP, (bob)