跳到主要内容
ecdsa.com

JAR 签名查看器

选择或拖放 Java 归档文件。文件在此页面中读取:每个条目的摘要与 META-INF/MANIFEST.MF 比对,每个 .SF 文件与清单比对,每个 .RSA、.EC 或 .DSA 块与其 .SF 比对,签名者的证书链则与你粘贴的根证书比对。

100% 本地运行——所有操作都在你的浏览器中完成,不会向任何服务器发送数据

来源:为测试套件编写的 JAR,使用本站公开的测试 PKI 通过 jarsigner(Temurin JDK 25)签名;jarsigner -verify -strict 接受了除混合签名示例之外的全部 JAR——tools/jar-signature-inspector/fixtures

.jar、.war、.ear 或 .aar 文件;APK 的 v1 签名也是 JAR 签名。
或拖放到此处

在浏览器中读取——文件绝不会上传。

你作为根信任的 PEM 证书——JDK 的 cacerts 或你公司的代码签名根证书。不提供时,仍会检查签名,但无法为签名者担保。

Three files sign an archive

A JAR is a ZIP file, and signing it adds files under META-INF/ rather than changing the archive, as the JAR File Specification describes:

  • The manifest, META-INF/MANIFEST.MF, lists every entry in a section of its own with a digest of its content (SHA-256-Digest: …).
  • A signature file per signer, META-INF/<NAME>.SF, holds digests of the manifest: of the whole file (SHA-256-Digest-Manifest), of its main attributes, and of each entry's section.
  • A signature block per signer, META-INF/<NAME>.RSA, .EC or .DSA, is a PKCS #7 SignedData whose signature covers the .SF file, with the signer's certificates and, when jarsigner -tsa was used, an RFC 3161 time-stamp token.

So an entry is protected by a chain of digests: its bytes by the manifest, the manifest by the signature file, the signature file by the signature. WAR and EAR files are JARs with other contents, and the v1 signature of an Android APK is a JAR signature too.

What jarsigner -verify checks, and the inspector with it

The inspector follows the semantics of Java's own JarVerifier. For each signer, the signature block must verify over its .SF file with the certificate it carries. The .SF must match the manifest — the whole-manifest digest when present, otherwise every section digest — exactly as Java accepts either. Then every entry of the archive is read and digested: an entry whose digest differs from the manifest is modified; a file the manifest does not list, or lists without a signer's section, is unsigned; a section whose entry is gone is missing. jarsigner -verify -strict fails on any of them, and so does the verdict here; the full list of entries with their status is below each result.

A signing certificate expires, and recent JDKs reject what they consider weak: a JAR signed with SHA-1 is treated as unsigned by them, which the inspector warns about. A time-stamp keeps a signature valid after its certificate expires, by proving it existed while the certificate was valid: the RFC 3161 token is verified and the signer's chain is checked at the time-stamped moment instead of now. The chain is checked against the root certificates you paste — your JDK's cacerts or your company's code-signing root; without one, the signatures are verified but the signer is reported as not vouched for, the case jarsigner reports as “PKIX path building failed”.

Several signers

Each signer has its own .SF and block, and each is verified on its own. They must agree on the manifest they sign: a second jarsigner run with another digest algorithm adds new digest lines to the manifest's sections, the first signer's section digests no longer match, and jarsigner -verify -strict fails — one of the examples shows exactly that.

The examples are JARs written for the test suite and signed with jarsigner from a Temurin JDK and this site's published test PKI, with the test root filled in as the trust anchor; jarsigner -verify -strict accepted all of them but the mixed-digest one, as the inspector does. APKs are checked with all their schemes by the APK signature inspector, Windows executables by the Authenticode inspector, and a time-stamp token on its own by the time-stamp token inspector.