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.
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.
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.
- 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.
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.
Build the JAR
Create the application or library artifact, such as myapp.jar, before production signing.
Calculate digests
Java signing records digest information associated with entries that participate in the signing structure.
Create signature
The signing operation uses the private key to create cryptographic signature information.
Associate identity
The signer certificate provides the public key and identity information needed during verification.
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.
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.
Signature file
The signature-related .SF file contains digest information associated with the manifest and provides data that participates in signature verification.
Signature block
A signature block such as .RSA, .DSA, or .EC contains cryptographic signature material and signer certificate information according to the signing configuration.
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.
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.
| Tool | Primary purpose | Typical role |
|---|---|---|
| keytool | Manage keys, certificates, and keystore entries | Create or inspect key material, manage certificates, aliases, and keystore contents. |
| jarsigner | Sign and verify JAR files | Apply a JAR signature and later verify its signing and certificate information. |
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.
Generate key pair
Create the private/public key pair and establish the alias used by the Java signing workflow.
Obtain certificate
Complete the applicable certificate request and validation process with the certificate authority.
Import chain
Store the signer certificate and applicable chain information with the signing material.
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.
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 TimestampingProtect Java signing credentials throughout release.
Keep private keys outside source code and restrict which build jobs can request signatures.
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
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.
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.
Manifest
Entry metadata and digest information establish what content participates in the integrity structure.
Entry digests
The digest relationship allows the verifier to detect changes in covered entries.
Signature file
The .SF file carries signature-related digest information for the manifest.
Signature block
The signature block contains cryptographic signature and signer certificate information.
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.
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 ChainJava 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.
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.
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.
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 ExpirationJava 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 is part of the certificate's defined validity period. It is normally planned for through certificate renewal and replacement procedures.
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 RevocationJava 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.
| Area | What to evaluate | Why it matters |
|---|---|---|
| Hash algorithms | Digest algorithm accepted by the signing and verification environment | Weak or disabled digest algorithms can prevent successful verification. |
| Signature algorithms | RSA or EC/ECDSA where supported and appropriate | Both the certificate and Java security configuration affect compatibility. |
| Algorithm constraints | Java security properties and provider rules | An algorithm can exist technically but still be rejected by current policy. |
| Legacy algorithms | Older or weak algorithms still present in historical artifacts | Newer 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.
Java version
Different releases can have different security defaults and disabled algorithms.
Security providers
Provider availability and configuration can influence supported cryptographic operations.
Certificate and signature
The certificate and selected signature algorithm must remain acceptable to the runtime.
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.
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.
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.
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.
Is the JAR actually signed?
Inspect the archive and verification output for the expected META-INF signature structure.
Which entries are signed?
Determine whether the affected class or resource is part of the signed content.
Does the signature verify?
Run the Java verification command and separate signature errors from certificate or trust errors.
Was signed content modified?
Compare the release artifact against the artifact that was actually signed.
Is the signer certificate valid?
Check certificate identity, validity period, usage, and status.
Does the certificate chain build?
Check intermediates, root trust, and the certificates available to the verification environment.
Is the signer trusted here?
Compare the environment's trust configuration with the certificate chain being presented.
Is the algorithm accepted?
Check Java security policies, disabled algorithms, providers, and version-specific constraints.
Is timestamp information valid?
Inspect timestamp presence and verification status when the signing workflow uses timestamping.
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.
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.
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 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.
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.
