Java Code Signing: Complete Guide

Java code signing is the process of digitally signing Java software, commonly JAR files, so the software can be associated with a signing identity and changes to signed content can be detected. Java signing uses a certificate and private key, with Java's JAR signing and verification mechanisms handling the signature information.

Java code signing is not the same as Windows Authenticode signing. Java has its own JAR signature structure, tooling, certificate handling, and verification behavior.

JAR signing jarsigner keytool Keystores Truststores
Java artifact Signed JAR
META-INF Manifest and signature metadata
Private Key Creates the cryptographic signature
Verification Integrity, identity and trust

What Java Code Signing Actually Does

Java code signing gives a Java artifact a cryptographic signature that can be checked later. For JAR-based software, the signing structure records digest information for relevant entries and associates that information with a signer through a certificate and signature.

The practical result is twofold: a verification process can detect changes to signed content, and the signer certificate provides identity information that a Java environment can evaluate against its Java truststore configuration.

That distinction matters. A valid signature is evidence about the integrity of signed content and the cryptographic identity behind the signature. It is not a statement that the application is safe, bug-free, or universally trusted.

What signing does not prove

  • The software is malware-free.
  • The software is free of security vulnerabilities.
  • The publisher is universally trustworthy.
  • The artifact was never compromised outside the signed content.

Java Code Signing at a Glance

The signing process becomes easier to understand when the artifact, cryptographic material, JAR metadata, and verification stage are treated as separate parts of one workflow.

1
Java/JAR FileFinal application or library artifact
2
Entry DigestsDigest information for signed entries
3
Private KeySecret signing credential
4
Digital SignatureCryptographic signing result
5
Signer CertificateIdentity and public key
6
JAR Signature FilesManifest and signature metadata
7
Java VerificationIntegrity, certificate and trust checks

What Can Be Signed in Java?

Java signing is primarily associated with JAR-based distribution. Unlike a Windows executable signing model, the JAR mechanism works around archive entries and signing metadata contained in the archive.

Common Java signing targets
  • JAR files used to distribute Java software.
  • Java libraries distributed as JAR artifacts.
  • Java applications packaged as executable or application JARs.
  • Other Java package and signing contexts where the applicable Java tooling supports signing.
Why the distinction matters

A JAR is an archive with structured entries. Java signing therefore cannot be reduced to the idea that one generic signature is simply attached to a ZIP file.

The signing and verification process uses JAR metadata and entry digest information to establish what signed content is being checked. The JAR signature structure includes the manifest, signature file, and signature block.

How Java JAR Signing Works

A signed JAR is built through several related operations. The important point is that signing happens after the artifact and its relevant contents have been finalized.

Step 01

Build the JAR

Create the application or library artifact, such as myapp.jar, before production signing.

Step 02

Calculate digests

Java signing records digest information associated with entries that participate in the signing structure.

Step 03

Create signature

The signing operation uses the private key to create cryptographic signature information.

Step 04

Associate identity

The signer certificate provides the public key and identity information needed during verification.

Step 05

Timestamp and release

Production signatures can be timestamped before the finalized artifact is verified and published.

Anatomy of a Signed JAR

The files under META-INF are central to understanding what Java signing actually places inside a JAR. Their roles are related, but they are not interchangeable.

myapp.jar
│
├── META-INF/
│ ├── MANIFEST.MF
│ ├── SIGNER.SF
│ └── SIGNER.RSA
│
├── com/example/App.class
├── com/example/Config.class
└── resources/...
MANIFEST

MANIFEST.MF

Contains manifest metadata and digest information associated with JAR entries. It forms an important part of the integrity chain used by JAR verification.

.SF

Signature file

The signature-related .SF file contains digest information associated with the manifest and provides data that participates in signature verification.

.RSA

Signature block

A signature block such as .RSA, .DSA, or .EC contains cryptographic signature material and signer certificate information according to the signing configuration.

ENTRIES

Application content

Classes, resources, and other JAR entries are the actual software content. Changes to signed entries can cause digest or signature verification failures.

Java Code Signing Certificate

The certificate is the identity layer around the public key. It does not create the signature itself. The private key performs that cryptographic operation.

Private KeySecret credential used to create the digital signature.
→
Digital SignatureCryptographic result associated with the signed information.
→
Public KeyUsed to verify the signature.
→
CertificateAssociates the public key with signer identity and certificate information.

A certificate also carries validity and usage information and can participate in a certificate chain. Whether that chain is trusted depends on the verification environment, its trust configuration, and the applicable security rules.

What Is Code Signing?

keytool vs jarsigner

These commands are often used together, but they solve different problems. Treating them as interchangeable creates confusion during key setup, signing, and verification.

ToolPrimary purposeTypical role
keytoolManage keys, certificates, and keystore entriesCreate or inspect key material, manage certificates, aliases, and keystore contents.
jarsignerSign and verify JAR filesApply a JAR signature and later verify its signing and certificate information.
A
keytoolCreate or manage key pair and certificate material.
B
jarsignerSign the finalized JAR using the selected alias.
C
jarsignerVerify the resulting signature and certificate data.

Java Keystores and Code Signing

A keystore is a container and management mechanism for cryptographic material. It should not be confused with the certificate, the private key, or a truststore.

Signing Keystore

Used to hold and manage signing-related material accessible to the signing process.

  • Key pair
  • Private key
  • Certificate
  • Alias
  • Keystore credentials

Truststore

Used by a Java environment to hold trusted certificates or trust anchors used when evaluating certificate chains.

  • Trusted certificates
  • Trust anchors
  • Environment-specific trust decisions
  • No production signing private key requirement

Common keystore formats include JKS and PKCS#12. The exact format and security configuration should be selected according to the Java version, deployment model, tooling, and integration requirements.

How to Create a Java Signing Key Pair

Key creation is the beginning of the signing lifecycle. The certificate issuance process is separate from the actual JAR signing operation.

1

Generate key pair

Create the private/public key pair and establish the alias used by the Java signing workflow.

2

Obtain certificate

Complete the applicable certificate request and validation process with the certificate authority.

3

Import chain

Store the signer certificate and applicable chain information with the signing material.

4

Protect access

Restrict private-key access and make the signing alias available only to the intended signing process.

For production environments, key generation and storage should be designed around the organization's signing architecture rather than treating a developer workstation keystore as the default long-term control.

How to Sign a JAR

Once the final JAR and signing material are available, jarsigner can apply the signature using the selected keystore and alias.

jarsigner \
  -keystore signing.p12 \
  myapp.jar \
  mykey

The keystore identifies where the signing material is managed, myapp.jar is the artifact being signed, and mykey is the alias that identifies the appropriate signing entry. In a real release pipeline, credentials should be supplied through controlled secret management rather than hard-coded into build files or source repositories. Private-key protection is essential when signing becomes part of automated releases.

The important operational rule is simple: sign after the artifact is finalized. If signed content is changed after signing, verification may fail because the digest information no longer corresponds to the current content.

Java JAR Signing and Timestamping

Timestamping adds signing-time evidence to a production signature. It becomes particularly relevant when a certificate has a finite validity period and software must remain verifiable after the original signing certificate reaches expiration.

JARFinal artifact prepared for release.
→
SignaturePrivate key signs the JAR signing information.
→
CertificateSigner identity and public key information.
→
TimestampIndependent signing-time evidence.
→
VerificationEnvironment evaluates the resulting signature.

A timestamp does not prevent later modification of a JAR. It also does not make an invalid signature valid. Code signing timestamping provides signing-time evidence rather than artifact protection. Its role is to provide evidence about when the signature was created, which can matter when certificate validity and long-term signature interpretation are evaluated.

Code Signing Timestamping

Protect Java signing credentials throughout release.

Keep private keys outside source code and restrict which build jobs can request signatures.

Explore Code Signing Implementation

How to Verify a Signed JAR

jarsigner is the primary Java command-line tool for checking a JAR signature. Verification should be treated as a set of related checks rather than a single yes/no certificate lookup.

jarsigner -verify -verbose -certs myapp.jar
JAR verification
$ jarsigner -verify -verbose -certs myapp.jar
jar verified.

Integrity: signed entries verified
Signer: certificate information available
Chain: certificate path evaluated
Timestamp: signing-time information inspected
Trust: environment-specific trust still matters

A successful cryptographic verification does not automatically mean that every Java installation will trust the signer. Verification can involve entry digests, the signature, signer certificate, certificate chain, certificate validity, trust configuration, timestamp information, and the consistency of the JAR's manifest and signature metadata. Certificate path validation depends on the code signing certificate chain and the trust configuration of the environment.

What Happens When a Signed JAR Is Modified?

The integrity model depends on the relationship between the signed entry data and the digest information recorded by the signing structure.

1
Original JAREntries match the signed state.
2
Content modifiedA signed class or resource changes.
3
Digest mismatchCurrent content no longer matches signed data.
4
Verification failureThe signature cannot validate the changed content.

Typical causes include modifying a class, changing a resource, repackaging a JAR, replacing signed content, removing signed content, or altering signature metadata. The exact verification result depends on what was changed and which parts of the signing structure are affected.

That is why release pipelines should avoid rebuilding, repackaging, or otherwise changing a signed artifact after the signing step. For repeatable release controls, use Java code signing in CI/CD. The artifact that leaves the signing boundary should be the artifact that gets verified and published.

How Java Determines Which Entries Are Signed

JAR signing is not simply a signature over the entire ZIP container as one undifferentiated block. Java's signing model works through entry metadata and the files under META-INF.

Layer 01

Manifest

Entry metadata and digest information establish what content participates in the integrity structure.

Layer 02

Entry digests

The digest relationship allows the verifier to detect changes in covered entries.

Layer 03

Signature file

The .SF file carries signature-related digest information for the manifest.

Layer 04

Signature block

The signature block contains cryptographic signature and signer certificate information.

Layer 05

Verification

Java uses these relationships to evaluate the signed artifact and its signer information.

Java Certificate Chain and Trust

The signer certificate can participate in a certificate chain that connects the signer identity to an issuing intermediate and a root trust anchor.

Signer CertificateIdentifies the signer and contains the public key.
→
Intermediate CAProvides the issuing path for the signer certificate.
→
Root CAActs as a trust anchor when trusted by the environment.

Cryptographic signature validity and certificate trust are related but distinct questions. A signature can be mathematically valid while the certificate is expired, the chain is incomplete, or the signer is not trusted by the Java environment performing the verification.

Code Signing Certificate Chain

Java Truststores and Trusted Certificates

Java deployments often require a clear separation between material used to sign software and certificates trusted when software or certificates are verified.

Keystore: signing side

The signing keystore is associated with cryptographic material used by the signing workflow. It may contain a private key, certificate, alias, and related metadata.

Access to private signing material should be tightly controlled because possession of the private key can allow someone to create signatures associated with that identity.

Truststore: verification side

A truststore provides certificates or trust anchors used by a Java environment when it evaluates certificate trust.

This explains why the same signed JAR can produce different trust outcomes in different environments with different trust configurations.

Java Code Signing and Certificate Expiration

A certificate's expiration date affects the signing lifecycle, but it should not be reduced to the claim that every historical signature instantly becomes meaningless on the expiration date.

Certificate issuedSigning identity becomes available.
JAR signedPrivate key creates signature.
TimestampedSigning-time evidence is recorded.
ReleasedUsers receive the signed artifact.
Certificate expiresNew signing requires current credentials.
ReplacementNew signing material can be provisioned.
Historical checksTimestamp and policy context can matter.

Production teams should monitor certificate expiration well before release operations are affected. Existing signed artifacts need to be evaluated according to the Java version, verification policy, timestamping model, and certificate status applicable to the environment.

Code Signing Certificate Expiration

Java Code Signing and Certificate Revocation

Revocation is different from expiration. It represents a deliberate change in the certificate's status, often associated with compromise, misuse, or another reason the certificate should no longer be trusted.

Expiration

Expiration is part of the certificate's defined validity period. It is normally planned for through certificate renewal and replacement procedures.

Revocation

Revocation changes the status of a certificate before or during its expected lifecycle. Verification behavior can depend on certificate status checking, timestamp information, and the policies of the Java environment.

Previously signed software therefore needs separate consideration from the simple question of whether a certificate is currently being used for new signing. Timestamping can be important when historical signatures are evaluated.

Code Signing Certificate Revocation

Java Code Signing Algorithms

Algorithm selection is a compatibility and security decision, not a static recommendation that can be separated from the Java environment. Signing and verification depend on the Java version, security providers, certificate, signature configuration, and enabled algorithm policies.

AreaWhat to evaluateWhy it matters
Hash algorithmsDigest algorithm accepted by the signing and verification environmentWeak or disabled digest algorithms can prevent successful verification.
Signature algorithmsRSA or EC/ECDSA where supported and appropriateBoth the certificate and Java security configuration affect compatibility.
Algorithm constraintsJava security properties and provider rulesAn algorithm can exist technically but still be rejected by current policy.
Legacy algorithmsOlder or weak algorithms still present in historical artifactsNewer Java environments may disable algorithms that older releases accepted.

Algorithm support depends on the Java version, security configuration, certificate, and signing tooling. Test production signing and verification on the Java versions that your users or deployment environments actually run.

Java Version Compatibility

A JAR that verifies successfully in one environment can encounter a trust or algorithm problem in another. The artifact has not necessarily changed; the verification rules or available providers may have.

A

Java version

Different releases can have different security defaults and disabled algorithms.

B

Security providers

Provider availability and configuration can influence supported cryptographic operations.

C

Certificate and signature

The certificate and selected signature algorithm must remain acceptable to the runtime.

D

Keystore format

Signing workflows also depend on the formats and providers supported by the Java tooling.

For release engineering, this means verification should be performed on representative Java versions rather than assuming that one successful developer-machine test establishes universal compatibility.

Java Code Signing in Build Systems

Java signing fits naturally into Maven, Gradle, Ant, and custom release automation. The exact integration differs by build system, but the security boundary should remain consistent.

BuildCompile and test source
Package JARCreate final artifact
SignUse protected key
TimestampAdd signing-time evidence
VerifyCheck final artifact
PublishRelease verified JAR

The key release rule is to sign after the artifact has been finalized. If packaging, dependency changes, resource injection, or other post-signing transformations alter covered content, the resulting JAR may no longer verify.

Build automation should therefore make signing a deliberate release stage rather than an incidental developer step.

Java Code Signing in CI/CD

A production signing pipeline should separate ordinary build permissions from the ability to use the signing key. This reduces the number of systems and identities that can create a release signature.

Source + BuildDevelopers commit code. Build agents compile, test, and package the JAR.
→
Controlled SigningA restricted stage requests signing using protected credentials and approved artifacts.
→
ReleaseTimestamped and verified artifacts move to publication and distribution.
✓
Keep signing credentials out of source repositories.
✓
Restrict which build identities can request signing.
✓
Use secret management for passwords and access credentials.
✓
Log signing operations and release identities.
✓
Verify the artifact immediately after signing.
✓
Consider HSM or cloud signing for higher-risk environments.

Java Code Signing With an HSM

An HSM can keep the private signing key inside a protected cryptographic boundary instead of exposing the raw key to an ordinary build machine.

jarsigner / Build SystemRequests a signing operation for an approved JAR artifact.
→
Protected Key ProviderConnects the Java signing workflow to the protected cryptographic key.
→
HSMPerforms the private-key operation while keeping the key protected.

HSM integration is not just a matter of placing a JAR command in front of hardware. Java cryptographic provider and configuration requirements can apply, and the build system must be designed to authenticate to the signing service or provider without exposing the private key.

Java Code Signing With PKCS#11

PKCS#11 can provide a Java integration path for cryptographic tokens and HSM-backed keys. The purpose here is architectural context rather than a complete provider configuration tutorial.

Java Cryptography Architecture

Java's cryptographic architecture provides the framework through which applications and tools access cryptographic operations and providers.

PKCS#11 provider/configuration

A compatible PKCS#11 integration can expose an HSM-backed key to the Java cryptographic stack according to the provider and runtime configuration.

HSM-backed key

The private key remains within the protected hardware boundary while signing operations are requested through the configured interface.

jarsigner

The signing tool can use the configured cryptographic environment to perform the JAR signing operation without requiring the raw private key on the build host.

Common Java JAR Signing Errors

Diagnosing failures by layer is more useful than treating every jarsigner message as an isolated problem.

Signing

  • Alias not found
  • Keystore cannot be opened
  • Private key unavailable
  • Certificate/key mismatch

Verification

  • JAR is unsigned
  • Signature verification failed
  • Digest mismatch
  • Modified signed entry

Certificate

  • Expired certificate
  • Revoked certificate
  • Wrong certificate
  • Untrusted certificate

Chain

  • Missing intermediate
  • Untrusted root
  • Certificate path problem
  • Truststore configuration

Algorithms

  • Disabled algorithm
  • Unsupported signature algorithm
  • Weak or legacy algorithm
  • Provider compatibility

Timestamp

  • Timestamp unavailable
  • Invalid timestamp
  • Timestamp verification problem
  • Signing-time information issue

How to Troubleshoot a JAR Signature Failure

Start with the artifact itself, then move outward through the signature, certificate, chain, trust environment, algorithms, and timestamp.

1

Is the JAR actually signed?

Inspect the archive and verification output for the expected META-INF signature structure.

2

Which entries are signed?

Determine whether the affected class or resource is part of the signed content.

3

Does the signature verify?

Run the Java verification command and separate signature errors from certificate or trust errors.

4

Was signed content modified?

Compare the release artifact against the artifact that was actually signed.

5

Is the signer certificate valid?

Check certificate identity, validity period, usage, and status.

6

Does the certificate chain build?

Check intermediates, root trust, and the certificates available to the verification environment.

7

Is the signer trusted here?

Compare the environment's trust configuration with the certificate chain being presented.

8

Is the algorithm accepted?

Check Java security policies, disabled algorithms, providers, and version-specific constraints.

9

Is timestamp information valid?

Inspect timestamp presence and verification status when the signing workflow uses timestamping.

10

Does another Java version behave differently?

Reproduce the verification on representative Java versions to identify environment-specific behavior.

Complete Java Code Signing Example

A production release can be understood as a lifecycle that begins with key material and ends with verification in the target Java environment.

Create key pairGenerate signing identity.
Obtain certificateComplete certificate issuance.
Build myapp.jarFinalize application artifact.
jarsignerCreate JAR signature.
TimestampRecord signing-time evidence.
VerifyCheck the final JAR.
PublishDistribute verified artifact.
!
Signed JARReleased artifact
↓
JAR ModifiedSigned entry changes
×
Digest MismatchSigned data no longer matches
!
Verification FailureSignature cannot validate the changed content

Java Code Signing Best Practices

Good Java signing practice is mainly about protecting the signing boundary, preserving artifact integrity, and making verification part of the release process.

✓
Sign the final JAR artifact after packaging is complete.
✓
Protect the private signing key from ordinary developer access where appropriate.
✓
Use an appropriate code signing certificate and maintain its lifecycle.
✓
Timestamp production signatures when the release model requires it.
✓
Run verification immediately after signing.
✓
Test verification on representative Java versions.
✓
Do not modify signed JAR content after the signing stage.
✓
Use controlled CI/CD signing rather than unrestricted workstation signing.
✓
Consider HSM or cloud signing for higher-risk production environments.
✓
Maintain certificate and signing-key inventory.
✓
Monitor certificate expiration before it affects release operations.
✓
Maintain replacement and compromise-response procedures.

Common Java Code Signing Misconceptions

Several common assumptions come from applying Windows signing concepts directly to Java. The underlying signing goals overlap, but the artifact and verification structures differ.

“Java code signing uses Authenticode.”
No. Java has its own JAR signing mechanism and metadata structure.
“A JAR signature encrypts the JAR.”
No. Signing provides cryptographic integrity and signer information. It is not encryption.
“The certificate signs the JAR.”
No. The private key creates the signature. The certificate associates the public key with signer identity.
“The whole ZIP is simply signed as one block.”
JAR signing has a specific entry, manifest, signature-file, and signature-block structure.
“A valid signature means the JAR is safe.”
No. A valid signature does not prove that the software is malware-free or vulnerability-free.
“A trusted certificate means every Java installation trusts it.”
No. Trust is evaluated by the verification environment and its trust configuration.
“A signed JAR can be modified without affecting verification.”
Modifying signed content can produce digest or signature verification failures.
“Keystore and truststore are the same.”
No. They serve different purposes in signing and certificate trust workflows.
“Certificate expiration and signature validity are always identical.”
Not necessarily. Timestamping and verification policy can affect interpretation of historical signatures.
“Timestamping prevents JAR modification.”
No. Timestamping provides signing-time evidence. It does not protect the artifact from later modification.

Java Code Signing FAQ

What is Java code signing?

Java code signing is the process of digitally signing Java software, commonly JAR files, so signed content can be checked for changes and associated with signer identity information through a certificate.

How does Java JAR signing work?

JAR signing uses digest information for relevant entries, a private key to create signature information, signer certificate data, and signature-related files under META-INF. Java tooling can later verify these relationships.

What is a signed JAR?

A signed JAR is a JAR containing Java signing metadata and cryptographic signature information that can be evaluated by compatible Java tooling and environments.

What certificate is used for Java code signing?

A certificate appropriate for the signing identity and Java signing workflow is used to associate a public key with the signer. The certificate itself does not create the signature.

What is jarsigner?

jarsigner is the Java command-line tool used to sign JAR files and verify JAR signatures.

What is keytool?

keytool is a Java utility for managing keys, certificates, aliases, and keystore entries.

What is the difference between keytool and jarsigner?

keytool primarily manages cryptographic material and keystores, while jarsigner signs and verifies JAR files.

What is inside a signed JAR?

A signed JAR commonly contains META-INF/MANIFEST.MF, a signature-related .SF file, a signature block such as .RSA, .DSA, or .EC, and the application classes and resources.

What are .SF and .RSA files?

The .SF file contains signature-related digest information, while a signature block such as .RSA contains cryptographic signature material and signer certificate information according to the signing configuration.

How do I sign a JAR file?

A common workflow is to prepare the final JAR, make the signing material available through a protected keystore or provider, and use jarsigner with the appropriate alias. Production workflows should also consider timestamping and post-signing verification.

How do I verify a signed JAR?

A common command is jarsigner -verify -verbose -certs myapp.jar. The output should be interpreted alongside certificate, chain, trust, algorithm, and timestamp information.

What happens if a signed JAR is modified?

If signed content is modified, its current digest may no longer match the digest information recorded during signing, causing verification to fail.

What is the difference between a Java keystore and truststore?

A keystore is used to manage cryptographic material such as signing keys and certificates. A truststore is used by a verification environment to hold trusted certificates or trust anchors.

Does Java code signing require timestamping?

Timestamping is an important production consideration when signatures may need to be interpreted after certificate expiration. The exact requirement depends on the signing and verification environment.

What happens when a Java signing certificate expires?

Expiration affects the ability to use that certificate for new signing and can affect verification according to the Java environment and signature context. Timestamp information can matter for historical signatures.

What happens when a Java signing certificate is revoked?

Revocation is a certificate-status change distinct from expiration. Verification behavior depends on status checking, timestamp information, and the security policy of the environment.

Can Java code signing use an HSM?

Yes. Java signing workflows can be integrated with HSM-backed keys through compatible cryptographic providers and configurations. The exact setup depends on the HSM and Java environment.

Can JAR signing be automated in CI/CD?

Yes. A common pipeline is build, test, package, controlled signing, timestamp, verification, and publish. Signing credentials should be protected and access should be restricted.

Why does a signed JAR work on one Java version but fail on another?

Java versions can differ in security defaults, disabled algorithms, providers, certificate handling, and trust configuration. The artifact may be unchanged while the verification environment behaves differently.

Why does jarsigner -verify report a signature or certificate error?

The cause can be an unsigned or modified entry, invalid signature data, an expired or untrusted certificate, an incomplete chain, an unsupported or disabled algorithm, a truststore issue, or a timestamp problem. Diagnose the failure by layer rather than by the error message alone.

Java Code Signing Resources

These cluster pages can expand individual implementation and troubleshooting topics without making this hub unnecessarily repetitive.

JAR SigningPractical JAR signing workflow and production considerations.
Signed JAR VerificationVerification commands, output interpretation, and diagnostic checks.
jarsignerJava JAR signing and verification utility.
keytool for Code SigningKeys, certificates, aliases, and keystore management.
Java Keystores & TruststoresSigning storage and verification trust serve different purposes.
JAR Signature StructureManifest, signature files, signature blocks, and JAR entries.
Java Code Signing ErrorsSigning, verification, certificate, and algorithm failures.
Java Code Signing in CI/CDAutomated signing, protected keys, verification, and release controls.

Build a Java signing workflow you can verify.

From JAR anatomy and jarsigner to protected keys, timestamps, certificate chains, and CI/CD controls, a reliable signing process starts with a clear separation between signing, integrity, and trust.

Automate Code Signing in CI/CD