---
source_url: https://www.pubnub.com/docs/security/encryption/encrypt-single-item
title: Encrypt and decrypt a single item
description: Encrypt individual message fields with a standalone CryptoModule, send them as Base64 text, and decrypt them on the receiver with the same module and cipher key.
updated_at: 2026-09-30T07:20:08.000Z
---

# Encrypt and decrypt a single item

> For AI agents: documentation index at https://www.pubnub.com/llms-full.txt

Use a standalone CryptoModule instance when you need to encrypt only some fields of a message rather than every message and file your app sends. A common case is Mobile Push Notifications: the push service (APNs or FCM) must read specific keys in the payload, so only sensitive fields should be encrypted.

For encrypting every message and file automatically, see [Encrypt and decrypt all messages and files](https://www.pubnub.com/docs/security/encryption/encrypt-all-messages-and-files.md).

## Before you start

Confirm you have:

* A PubNub keyset with publish and subscribe keys from [Admin Portal](https://admin.pubnub.com/).
* A cipher key shared by all clients that need to read the encrypted fields. Use a 32-character string as the cipher key for AES-256 encryption.
* Do **not** register a CryptoModule in the PubNub configuration for this approach. If a module is registered in config, all messages and files are encrypted automatically. Use a standalone instance instead.

## Encrypt a field and decrypt it on the receiver

The encrypted value is binary data, and a PubNub message is JSON, so the sender sends the value as Base64 text. The sender and the receiver use the same standalone module with the same cipher key:

1. On both sides, create a standalone AES-CBC CryptoModule with the shared cipher key.
2. On the sender, serialize the field value to JSON, encrypt its UTF-8 bytes, and put the Base64 encoding of the result in the message.
3. On the receiver, Base64-decode the field, decrypt it with the same module, and parse the decrypted UTF-8 bytes as JSON.

### JavaScript

```javascript
// Both sides create the same standalone module with the same cipher key.
const cryptoModule = PubNub.CryptoModule.aesCbcCryptoModule({ cipherKey: 'pubnubenigma' });

function toBase64(buffer) {
  let binary = '';
  for (const byte of new Uint8Array(buffer)) binary += String.fromCharCode(byte);
  return btoa(binary);
}

// Sender: encrypt the results object and send the ciphertext as Base64 text.
const results = { test_name: 'pregnancy', results: 'positive', notes: 'You are having twins!' };
const encrypted = cryptoModule.encrypt(JSON.stringify(results));

await pubnub.publish({
  channel: 'test-results',
  message: {
    pn_apns: { aps: { alert: 'Your test results are available.' } },
    results: toBase64(encrypted),
  },
});

// Receiver: decrypt() accepts the Base64 text and returns the UTF-8 bytes of the JSON.
subscription.onMessage = (event) => {
  const decrypted = cryptoModule.decrypt(event.message.results);
  const receivedResults = JSON.parse(new TextDecoder().decode(decrypted));
  // receivedResults.notes === 'You are having twins!'
};
```

### Swift

```swift
struct TestResults: Codable, Equatable {
  let testName: String
  let results: String
  let notes: String

  enum CodingKeys: String, CodingKey {
    case testName = "test_name"
    case results
    case notes
  }
}

// Both sides create the same standalone module with the same cipher key.
let cryptoModule = CryptoModule.aesCbcCryptoModule(with: "pubnubenigma")

// Sender: encrypt the results object and send the ciphertext as Base64 text.
let results = TestResults(testName: "pregnancy", results: "positive", notes: "You are having twins!")

do {
  let encrypted = try cryptoModule.encrypt(data: JSONEncoder().encode(results)).get()
  let message = AnyJSON([
    "pn_apns": ["aps": ["alert": "Your test results are available."]],
    "results": encrypted.base64EncodedString()
  ])
  pubnub.publish(channel: "test-results", message: message) { result in
    if case let .failure(error) = result { print("Publish failed: \(error)") }
  }
} catch {
  print("Encryption failed: \(error)")
}

// Receiver: decode the Base64 text, decrypt it, and decode the JSON.
subscription.onMessage = { message in
  do {
    guard
      let base64 = message.payload[rawValue: "results"] as? String,
      let encrypted = Data(base64Encoded: base64)
    else { return }
    let decrypted = try cryptoModule.decrypt(data: encrypted).get()
    let receivedResults = try JSONDecoder().decode(TestResults.self, from: decrypted)
    // receivedResults.notes == "You are having twins!"
  } catch {
    print("Decryption failed: \(error)")
  }
}
```

### Java

```java
// Both sides create the same standalone module with the same cipher key.
CryptoModule cryptoModule = CryptoModule.createAesCbcCryptoModule("pubnubenigma", true);

// Sender: encrypt the results object and send the ciphertext as Base64 text.
JsonObject results = new JsonObject();
results.addProperty("test_name", "pregnancy");
results.addProperty("results", "positive");
results.addProperty("notes", "You are having twins!");
byte[] encrypted = cryptoModule.encrypt(results.toString().getBytes(StandardCharsets.UTF_8));

JsonObject aps = new JsonObject();
aps.addProperty("alert", "Your test results are available.");
JsonObject pnApns = new JsonObject();
pnApns.add("aps", aps);
JsonObject message = new JsonObject();
message.add("pn_apns", pnApns);
message.addProperty("results", Base64.getEncoder().encodeToString(encrypted));

pubnub.channel("test-results").publish(message).async(result ->
        result.onFailure(error -> System.err.println("Publish failed: " + error)));

// Receiver: decode the Base64 text, decrypt it, and parse the JSON.
subscription.setOnMessage(event -> {
    try {
        String base64 = event.getMessage().getAsJsonObject().get("results").getAsString();
        byte[] decrypted = cryptoModule.decrypt(Base64.getDecoder().decode(base64));
        JsonObject receivedResults = JsonParser.parseString(new String(decrypted, StandardCharsets.UTF_8))
                .getAsJsonObject();
        // receivedResults.get("notes").getAsString() is "You are having twins!"
    } catch (Exception error) {
        System.err.println("Decryption failed: " + error);
    }
});
```

The module uses a random initialization vector, so the encrypted value is different every time, even for the same input. The receiver doesn't need the initialization vector separately, because the module stores it in the header of the encrypted data.

## APNs push notification example

This example shows the partial encryption pattern for an Apple Push Notification Service (APNs) payload. The push service must read `pn_apns.aps` in plain text. Only the `results` object contains sensitive data, so it is encrypted while everything else stays clear.

**Before encryption:**

```json
{
  "pn_apns": {
    "aps": {
      "alert": "Your test results are available.",
      "sound" : "bingbong.aiff"
    }
  },
  "results": {
    "test_name": "pregnancy",
    "results": "positive",
    "notes": "You are having twins!"
  }
}
```

Encrypt only the `results` object with the standalone CryptoModule, as shown in [Encrypt a field and decrypt it on the receiver](#encrypt-a-field-and-decrypt-it-on-the-receiver), then put the Base64 text in the payload in place of the object.

**After encryption:**

```json
{
  "pn_apns": {
    "aps": {
      "alert": "Your test results are available.",
      "sound" : "bingbong.aiff"
    }
  },
  "results": "UE5FRAFBQ1JIEAEUspEt4SaiAQxmx+weao+/JtzL1W440jYF66t4u6CkEEuhNspuS0BKSOTvx7FP7UDk+eX6/T2yNVYNfes9SwYjoyU435r9HX3BWvoJExErLlsWx/++dz1kLndrt9QhXw=="
}
```

:::note Push payload constraints
Do not encrypt APNs or FCM keys, or any values that the push service must parse as plain text. Encrypt only the fields your application reads after delivery.
:::

Last updated at: 2026-09-30T07:20:08.000Z
