本文へスキップ
ecdsa.com

JAR 署名インスペクター

Java アーカイブを選択またはドロップしてください。ファイルはこのページ内で読み込まれます。各エントリのダイジェストを META-INF/MANIFEST.MF と、各 .SF ファイルをマニフェストと、各 .RSA、.EC、.DSA ブロックを対応する .SF と照合し、署名者の証明書チェーンを貼り付けたルート証明書と照合します。

100% ローカル:すべてブラウザー内で処理され、どのサーバーにも何も送信されません

出典:テストスイート用に作成し、当サイトが公開しているテスト PKI を使って jarsigner(Temurin JDK 25)で署名した JAR です。ダイジェストが混在する例を除き、いずれも jarsigner -verify -strict で受理されています(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.