---
title: "PGP Integration with JCE Provider and Bouncy Castle"
slug: "fortanix-dsm-pgp-integration-with-jce-provider-and-bouncy-castle"
updated: 2026-07-30T08:13:28Z
published: 2026-07-30T08:13:28Z
canonical: "support.fortanix.com/fortanix-dsm-pgp-integration-with-jce-provider-and-bouncy-castle"
---

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

# PGP Integration with JCE Provider and Bouncy Castle

## 1.0 Introduction

This article explains how to manage Pretty Good Privacy (PGP) keys using **Fortanix-Data-Security-Manager (DSM)** in **Java environments with Bouncy Castle (BC)**. It covers both new and existing key integrations, along with example implementations for encryption and decryption using the Fortanix JCE Provider.

Bouncy Castle (BC) is a widely used Java library that supports PGP cryptography through the Java Cryptographic Architecture (JCA) provider model. Fortanix DSM integrates seamlessly with this model by offering a pluggable JCE provider that enables secure key management directly from DSM. *For more information, refer to the* [*Bouncy Castle official documentation*](https://www.bouncycastle.org/)*.*

With this integration, applications can fetch private keys from DSM in memory and use them in PGP operations with BC. You can further enhance security using API authentication and optional IP-based access restrictions. *For more information, refer to* [*Clients: Java Cryptography Extension (JCE) Provider*](/v1/docs/clients-java-cryptography-extension-jce-provider)*.*

![PGP.png](https://cdn.us.document360.io/c3bd85d2-4ad8-4d85-9f60-f1c168a3aad9/Images/Documentation/pgp.png)

**Figure 1: Architecture workflow**

## 2.0 Prerequisites

Ensure the following:

- Download [Fortanix DSM JCE Provider](https://fortanix.zendesk.com/hc/en-us/articles/360018362951-JCE) **version 4.8.2069** or later, as this includes required enhancements for PGP integration.
- Run the following command to copy the downloaded JAR file to the following directory in your Java installation:

```bash
bashCopyEdit$JAVA_HOME/jre/lib/ext
```

## 3.0 Configure Fortanix DSM

A Fortanix DSM service must be configured, and the URL must be accessible. To create a Fortanix DSM account and group, refer to the following sections:

### 3.1 Signing Up

To get started with the Fortanix DSM cloud service, you must register an account at <Your_DSM_Service_URL>. For example, [https://amer.smartkey.io.](https://amer.smartkey.io.) On-premises customers use the KMS URL, and the SaaS customers can use the URLs as listed [*here*](https://support.fortanix.com/hc/en-us/articles/4406135346068-Fortanix-DSM-SaaS-Global-Availability-Map) based on the application region.

*For more information on how to set up the Fortanix DSM, refer to the* [*Sign Up for Fortanix Data Security Manager SaaS*](https://support.fortanix.com/docs/users-guide-sign-up-for-fortanix-data-security-manager-saas)*.*

### 3.2 Creating an Account

Access <Your_DSM_Service_URL> in a web browser and enter your credentials to log in to Fortanix DSM.

![](https://cdn.us.document360.io/c3bd85d2-4ad8-4d85-9f60-f1c168a3aad9/Images/Documentation/DSM_SaaS_Login_page(15).png)

**Figure 2: Logging in**

*For more information on how to set up an account in Fortanix DSM, refer to the* [*Getting Started with Fortanix Data Security Manager - UI*](https://support.fortanix.com/docs/users-guide-getting-started-with-fortanix-data-security-manager-ui)*.*

### 3.3 Creating a Group

Perform the following steps to create a group in the Fortanix DSM:

1. In the DSM left navigation panel, click the **Groups** menu item, and then click **ADD GROUP** to create a new group.

![](https://cdn.us.document360.io/c3bd85d2-4ad8-4d85-9f60-f1c168a3aad9/Images/Documentation/Add-Group(79).png)

**Figure 3: Add groups**
2. On the **Adding new group** page:
  1. **Title**: Enter a name for your group.
  2. **Description**(optional): Enter a short description of the group.
3. Click **SAVE** to create the new group.

*For more information about groups, refer to* [*Definitions*](/v1/docs/dsm-definitions#40-groups)*.*

> [!NOTE]
> TIP
> 
> It is recommended to configure a **Key undo policy** for groups for the cryptographic keys used by the application before creating or using the keys. Without a configured **Key undo policy**, key deletion is permanent and the deleted key cannot be recovered. Deleting an encryption key may result in permanent loss of access to the protected data and service disruption for applications that depend on the deleted key. *For detailed steps, refer to* [*Key Undo Policy*](/v1/docs/fortanix-dsm-key-undo-policy)*.*

### 3.4 Creating an Application

Perform the following steps to create an application (app) in the Fortanix DSM:

1. In the DSM UI left navigation panel, click the **Apps** menu item, and then click **ADD APP** to create a new app.

![](https://cdn.us.document360.io/c3bd85d2-4ad8-4d85-9f60-f1c168a3aad9/Images/Documentation/Add-App(2).png)

**Figure 4: Add application**
2. On the **Adding new app** page:
  1. **App name**: Enter the name for your application.
  2. **ADD DESCRIPTION** (optional): Enter a short description of the application.
  3. **Authentication method**: Select the default **API Key** as the authentication method from the drop down menu. *For more information on these authentication methods, refer to* [*Authentication*](https://support.fortanix.com/docs/users-guide-authentication)*.*
  4. **Assigning the new app to groups**: Select the group created in [*Section 3.3: Creating a Group*](/v1/docs/pgp-integration-with-jce-provider-and-bouncy-castle#33-creating-a-group) [](/v1/docs/using-data-security-manager-with-idcentral-key-management#43-creating-a-group)from the list.
3. Click **SAVE** to add the new application.

*For more information about applications, refer to* [*Definitions*](https://support.fortanix.com/docs/dsm-definitions#50-applications)*.*

### 3.5 Copying the API Key

Perform the following steps to copy the API key from the Fortanix DSM:

1. In the DSM UI left navigation panel, click the **Apps** menu item, and then click the app created in [*Section 3.4: Creating an Application*](/v1/docs/pgp-integration-with-jce-provider-and-bouncy-castle#34-creating-an-application) to go to the detailed view of the app.
2. On the **INFO** tab, click **VIEW API KEY DETAILS**.
3. From the **API Key Details** dialog box, copy the **API Key** of the app to use it later.

### 3.6 Creating a Security Object

Perform the following steps to generate an RSA key in the Fortanix DSM:

1. In the DSM UI left navigation panel, click the **Security Objects** menu item, and then click **ADD SECURITY OBJECT** to create a new security object.

![](https://cdn.us.document360.io/c3bd85d2-4ad8-4d85-9f60-f1c168a3aad9/Images/Documentation/Add-SO.png)

**Figure 5: Adding security object**
2. On the **Add new Security Object** page:
  1. **Security Object name**: Enter the name for your security object.
  2. **Group**: Select the group as created in [*Section 3.3: Creating a Group*](/v1/docs/pgp-integration-with-jce-provider-and-bouncy-castle#33-creating-a-group).
  3. Select **GENERATE**.
  4. In the **Choose a type** section, select the **RSA** key type.
  5. In the **Key Size** section, select the size of the key in bits.
  6. In the **Key operations permitted** section, select the required operations to define the actions that can be performed with the cryptographic keys, such as encryption, decryption, signing, and verifying.

> [!NOTE]
> NOTE
> 
> Ensure to select the **Export** permission.
3. Click **GENERATE** to create the new security object.

![](https://cdn.us.document360.io/c3bd85d2-4ad8-4d85-9f60-f1c168a3aad9/Images/Documentation/2025-07-02_21-00-20(1).png)

**Figure 6: Generate RSA key**

*For more information about security objects, refer to* [*Definitions*](https://support.fortanix.com/docs/dsm-definitions#60-security-objects)*.*

## 4.0 Encrypt with Fortanix PGP Key

The sample code below demonstrates how to load an existing RSA key from Fortanix DSM and prepare it for PGP file encryption using the Java SDK and BC library.

```bash
import com.fortanix.sdkms.v1.model.SobjectDescriptor;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair;
import java.security.*;
public class Sample {
static {
Security.addProvider(SdkmsJCE.getInstance());
Security.addProvider(new BouncyCastleProvider());
}
public static void main(String args[]) {
com.fortanix.sdkms.jce.provider.RSAPrivateKeyImpl privKey = new com.fortanix.sdkms.jce.provider.RSAPrivateKeyImpl(new SobjectDescriptor().name("PGP-RSA-Key")); // name of RSA Key in DSM
com.fortanix.sdkms.jce.provider.RSAPublicKeyImpl pubKey = new com.fortanix.sdkms.jce.provider.RSAPublicKeyImpl(new SobjectDescriptor().name("PGP-RSA-Key")); // name of same RSA Key in DSM
KeyPair kp = new KeyPair(pubKey, privKey);
PGPKeyPair pgpKp = new JcaPGPKeyPair(
PGPPublicKey.RSA_GENERAL, kp, new Date());
// continue using pgpKp for BC based PGP operations.
}
}
```

Set the following environment variables to enable authentication with Fortanix DSM:

- `FORTANIX_API_ENDPOINT` refers to the URL of your Fortanix DSM API endpoint.
- `FORTANIX_API_KEY` refers the Fortanix DSM API key as copied in [*Section 3.5: Copying the API Key*](/v1/docs/pgp-integration-with-jce-provider-and-bouncy-castle#35-copying-the-api-key).

You can configure these variables either through your system environment, a configuration file, or programmatically within your application before initializing the Fortanix SDK.

## 5.0 Encrypt with Existing PGP Key

To import existing public and private PGP keys into Fortanix DSM, use either the Fortanix Java-based PGP Key Importer JAR or the Fortanix `sq-dsm` CLI tool.

For file-based keystores in standard formats like JKS or P12, you can leverage the Java `keytool` utility to import the keystore directly into Fortanix DSM.

Below is a Linux example to run in the CLI where the Fortanix JAR is installed; this command also works on Windows CMD:

```bash
$ export FORTANIX_API_ENDPOINT=https://pkidsmtest.dhl.com
$ export FORTANIX_API_KEY=
$ keytool -importkeystore -srckeystore pgp-ks.jks -destkeystore dsm-ks -deststoretype SDKMS -destProviderName sdkms-jce
```

This command imports the private key into Fortanix DSM. After import, verify the key name in the Fortanix DSM user interface (UI) and use it as described in [*Section 4.0: Encrypt with Fortanix PGP Key*](/v1/docs/pgp-integration-with-jce-provider-and-bouncy-castle#40-encrypt-with-fortanix-pgp-key).

## 6.0 **Example**

This section demonstrates how to perform encryption and decryption using Bouncy Castle alongside the Fortanix JCE Provider.

The code snippet below exports the RSA public and private keys from Fortanix DSM into memory, then encrypts plaintext and decrypts the ciphertext back to plaintext.

Add the following Maven dependencies to your project:

```bash
<dependencies>
 <!--bouncy castle jdk15on 1.69-->
    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcpg-jdk15on</artifactId>
        <version>1.69</version>
    </dependency>

 <!--fortanix jce provider 4.8.2069-->
    <dependency>
        <groupId>com.fortanix</groupId>
        <artifactId>sdkms-jce-provider</artifactId>
        <version>4.8.2069</version>
    </dependency>
</dependencies>
```

Register the security providers in your Java code:

```bash
public static BouncyCastleProvider provider = new BouncyCastleProvider();

static {
    Security.addProvider(SdkmsJCE.getInstance());
    Security.addProvider(provider);
}
```

The following example exports keys from Fortanix DSM and performs encryption and decryption:

```bash
public static void main(String args[]) throws PGPException, IOException {

    RSAPrivateKeyImpl privKey = new RSAPrivateKeyImpl(new SobjectDescriptor().name("PgpKeyPublic")); // name of the public RSA Key in DSM

    RSAPublicKeyImpl pubKey = new RSAPublicKeyImpl(new SobjectDescriptor().name("PgpKeyPrivate")); // name of the private RSA Key in DSM

    KeyPair kp = new KeyPair(pubKey, privKey);

    PGPKeyPair pgpKp = new JcaPGPKeyPair(PGPPublicKey.RSA_GENERAL, kp, new Date()); 

    // continue using pgpKp for BC based PGP operations.
    byte[] byteArr = encrypt(PLAIN.getBytes(), pgpKp.getPublicKey());
    decrypt(byteArr, privKey ,pgpKp.getPrivateKey());
}
```

Replace `"PgpKeyPrivate"` and `"PgpKeyPublic"` with the actual key names from your Fortanix DSM UI.

### 6.1 Encryption

```bash
public static byte[] encrypt(byte[] bytes, PGPPublicKey pgpPublicKey) throws IOException {
    try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
        byte[] compressedData = compress(bytes);

        PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(
                new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5)
                        .setWithIntegrityPacket(true)
                        .setSecureRandom(new SecureRandom())
                        .setProvider(provider));

        encGen.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(pgpPublicKey).setProvider(provider));

        ArmoredOutputStream aOut = new ArmoredOutputStream(byteArrayOutputStream);
        OutputStream cOut = encGen.open(aOut, compressedData.length);
        cOut.write(compressedData);
        cOut.close();
        aOut.close();

        System.out.println("Encrypted message -> " + byteArrayOutputStream.toString());
        return byteArrayOutputStream.toByteArray();
    } catch (PGPException e) {
        System.err.println("Exception encountered while encoding data. "+e);
    }
    return new byte[0];
}

private static byte[] compress(byte[] clearData) throws IOException {
    try (ByteArrayOutputStream bOut = new ByteArrayOutputStream()) {
        PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(CompressionAlgorithmTags.ZIP);
        OutputStream cos = comData.open(bOut);
        PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator();
        OutputStream pOut = lData.open(cos,
                PGPLiteralData.BINARY,
                PGPLiteralData.CONSOLE,
                clearData.length,
                new Date());
        pOut.write(clearData);
        pOut.close();
        comData.close();
        return bOut.toByteArray();
    }
}
```

### 6.2 Decryption

```bash
public static void decrypt(byte[] encrypted, RSAPrivateKeyImpl privKey, PGPPrivateKey pgpKey)
          throws IOException, PGPException {
    InputStream in = new ByteArrayInputStream(encrypted);

    in = PGPUtil.getDecoderStream(in);
    JcaPGPObjectFactory pgpF = new JcaPGPObjectFactory(in);
    PGPEncryptedDataList enc;

    Object o = pgpF.nextObject();
    // the first object might be a PGP marker packet.
    if (o instanceof PGPEncryptedDataList) {
       enc = (PGPEncryptedDataList) o;
    } else {
        enc = (PGPEncryptedDataList) pgpF.nextObject();
    }

    PGPPublicKeyEncryptedData pbe = null;
    Iterator it = enc.getEncryptedDataObjects();

    pbe = (PGPPublicKeyEncryptedData) it.next();

    InputStream clear = pbe.getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder().setProvider(provider).build(privKey));
    JcaPGPObjectFactory plainFact = new JcaPGPObjectFactory(clear);
    Object message = plainFact.nextObject();
    String content = null;
    if (message instanceof PGPCompressedData) {
       PGPCompressedData cData = (PGPCompressedData) message;
       JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(cData.getDataStream());
       message = pgpFact.nextObject();
    }
    if (message instanceof PGPLiteralData) {
       PGPLiteralData ld = (PGPLiteralData) message;
       content = new String(IOUtils.toByteArray(ld.getInputStream()));
       System.out.println("Decrypted message -> " + content);
    } else if (message instanceof PGPOnePassSignatureList) {
        throw new PGPException("encrypted message contains a signed message - not literal data.");
    } else {
        throw new PGPException("message is not a simple encrypted file - type unknown.");
    }

    if (pbe.isIntegrityProtected()) {
       if (!pbe.verify()) {
           System.err.println("message failed integrity check");
       } else {
           System.out.println("message integrity check passed");
       }
    } else {
        System.out.println("no message integrity check");
    }
}
```

### 6.3 Result

```bash
Encrypted message -> -----BEGIN PGP MESSAGE-----
Version: BCPG v1.69

hQEMA3LmYCeNaKUKAQgAm6Ip7AoYsxqRssXyTa2o8MF4E8UdXVoMIPAyD9wwafRh
4+1nr/RD8i1UAoGupJR3/lVC90QlJn3axvyFu2mrXvkBDWUTWCfHaitHy1/24bOa
O7jV3RvW6ZQoZqlFfbR8iu/zVxoSIZfCv1FQ+ZcylRR0pZIBtOwXe6tp7jC7t0eI
hGYue5pJXKLbeDfgg7Rrnw5TXuN5TPo9anlzt0RsRzQAaNwtZmaZobme7XkuhXij
90RM9Xpw44zsTSB30EZB8jNTqiXQXnxZsVzDXeLExF9kexMjSASmCAkdr7wYUaZn
JQAEtShubJBDZSwk6tTNy8eAgJvQmLX2PztqdYVvytJTAcEIxKXnzRP2AfL3PUSg
lOG3paOi3PonkRUTJN5nqoe7S0Vw7lHo21UQEVJlRW3bTcFz7V7kKZ1NGh90GoJ9
ikHzzoaD+iVICZNZP4Qds4USuII=
=h56K
-----END PGP MESSAGE-----

Decrypted message -> SDKMS JCE Encryption/Decryption Test
```

![PGPResult.png](https://cdn.us.document360.io/c3bd85d2-4ad8-4d85-9f60-f1c168a3aad9/Images/Documentation/pgpresult.png)

**Figure 7: Results**

Fortanix Data Security Manager (DSM) is the world’s first cloud service secured with Intel® SGX. With Fortanix DSM, you can securely generate, store, and use cryptographic keys and certificates, as well as other secrets such as passwords, API keys, tokens, or any blob of data. Your business-critical applications and containers can integrate with Fortanix DSM using legacy cryptographic interfaces (PKCS#11, CNG, and JCE) or using the native Fortanix DSM RESTful interface.
