> ## Documentation Index
> Fetch the complete documentation index at: https://infisical.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Sign JARs with jarsigner

> Use the Infisical PKCS#11 module to sign Java artifacts with jarsigner.

<Info>
  This guide assumes your Product Admin has already created a [Signer](/documentation/platform/pki/code-signing/signers) and assigned you to it. If the signer has an approval policy, you'll also need [active access](/documentation/platform/pki/code-signing/approvals#access-lifecycle) before signing.
</Info>

Sign Java JAR files using `jarsigner` with the Infisical PKCS#11 module. The module implements the PKCS#11 v2.40 standard, allowing standard signing tools to use Infisical signers without code changes.

## Prerequisites

* A [Signer](/documentation/platform/pki/code-signing/signers) created by your Product Admin
* [Active signing access](/documentation/platform/pki/code-signing/approvals#access-lifecycle) (if an approval policy is attached)
* A [machine identity](/documentation/platform/identities/machine-identities) added to the Signer
* The Infisical [PKCS#11 module](/documentation/platform/pki/code-signing/pkcs11-module) installed and configured
* Java JDK 9 or later (for the `-addprovider` flag)

## Step 1: Set Up Authentication

Configure the Infisical PKCS#11 module with your machine identity credentials. Without this, the signing commands below fail with an auth error.

Create `/etc/infisical/pkcs11.conf` (or set `INFISICAL_CONFIG` to point elsewhere):

```yaml theme={"dark"}
auth:
  method: universal-auth
  universal_auth:
    client_id: "<machine-identity-client-id>"
    client_secret: "<machine-identity-client-secret>"

signer:
  id: "<signer-id>"
```

You can also pass the credentials via environment variables:

```bash theme={"dark"}
export INFISICAL_UNIVERSAL_AUTH_CLIENT_ID="<machine-identity-client-id>"
export INFISICAL_UNIVERSAL_AUTH_CLIENT_SECRET="<machine-identity-client-secret>"
```

<Note>
  Environment variables override values from the config file.
</Note>

For the full set of options, see the [PKCS#11 module configuration reference](/documentation/platform/pki/code-signing/pkcs11-module#configuration).

## Step 2: Create the SunPKCS11 Provider Configuration

Create a configuration file for Java's SunPKCS11 provider. Save it as `infisical-pkcs11.cfg`:

```
name = Infisical
library = /usr/local/lib/libinfisical-pkcs11.so
```

<Note>
  On macOS, use the `.dylib` extension. On Windows, use `.dll`.
</Note>

If you have multiple signers and want to target a specific one, add the `slot` parameter:

```
name = Infisical
library = /usr/local/lib/libinfisical-pkcs11.so
slot = 0
```

## Step 3: Sign a JAR

Use `jarsigner` with the PKCS#11 provider to sign your JAR file:

```bash theme={"dark"}
jarsigner \
  -keystore NONE \
  -storetype PKCS11 \
  -addprovider SunPKCS11 \
  -providerArg infisical-pkcs11.cfg \
  -sigalg SHA256withRSA \
  myapp.jar \
  "release-signer"
```

<Note>
  * `-keystore NONE`: Required when using PKCS#11 (no file-based keystore).
  * `-storetype PKCS11`: Tells jarsigner to use the PKCS#11 provider.
  * `-sigalg`: Must match the signer's key type. Use `SHA256withRSA` for RSA keys or `SHA256withECDSA` for EC keys.
  * The last argument (`release-signer`) is the **signer name** (the token label in PKCS#11).
</Note>

When prompted for a keystore password, you can either press Enter (the module authenticates automatically using the credentials from your environment variables or config file) or provide the PIN in the format `clientId:clientSecret`.

### Verify the Signature

After signing, verify the JAR signature:

```bash theme={"dark"}
jarsigner -verify -verbose myapp.jar
```

The output indicates the JAR is signed and verified:

```
jar verified.
```

## CI/CD Integration

For automated signing in CI/CD pipelines, use environment variables for credentials and suppress the password prompt:

```bash theme={"dark"}
export INFISICAL_UNIVERSAL_AUTH_CLIENT_ID="${INFISICAL_CLIENT_ID}"
export INFISICAL_UNIVERSAL_AUTH_CLIENT_SECRET="${INFISICAL_CLIENT_SECRET}"
export INFISICAL_CONFIG="/path/to/pkcs11.conf"

jarsigner \
  -keystore NONE \
  -storetype PKCS11 \
  -addprovider SunPKCS11 \
  -providerArg infisical-pkcs11.cfg \
  -sigalg SHA256withRSA \
  -storepass "" \
  myapp.jar \
  "release-signer"
```

<Note>
  * Use `-storepass ""` to avoid the interactive password prompt in non-interactive environments.
  * Ensure your machine identity has active signing access before the build starts. You can automate access requests via the Infisical API.
</Note>

## Troubleshooting

For any issue, start by enabling debug logging in your config file to get detailed output:

```json theme={"dark"}
{
  "log_level": "debug",
  "log_file": "/tmp/infisical-pkcs11.log"
}
```

<AccordionGroup>
  <Accordion title="CKR_GENERAL_ERROR when signing">
    This typically means the signing request was denied by the server. Check that you have active signing access for the signer. You can verify this in the Infisical UI by opening the signer's **Approvals** tab and looking at the **Requests** panel.
  </Accordion>

  <Accordion title="No slots visible or authentication errors">
    Verify that your credentials are correct and that the machine identity has been added to the Signer.
  </Accordion>
</AccordionGroup>

## What's Next?

<CardGroup cols={2}>
  <Card title="Sign Android APKs" icon="android" href="/documentation/platform/pki/guides/code-signing/apksigner">
    Sign Android applications with apksigner
  </Card>

  <Card title="Sign with OpenSSL" icon="lock" href="/documentation/platform/pki/guides/code-signing/openssl">
    Use OpenSSL with the PKCS#11 module
  </Card>
</CardGroup>
