Encrypt and decrypt a single item
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.
Before you start
Confirm you have:
- A PubNub keyset with publish and subscribe keys from Admin Portal.
- 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:
- On both sides, create a standalone AES-CBC CryptoModule with the shared cipher key.
- 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.
- On the receiver, Base64-decode the field, decrypt it with the same module, and parse the decrypted UTF-8 bytes as JSON.
- JavaScript
- Swift
- Java
1// Both sides create the same standalone module with the same cipher key.
2const cryptoModule = PubNub.CryptoModule.aesCbcCryptoModule({ cipherKey: 'pubnubenigma' });
3
4function toBase64(buffer) {
5 let binary = '';
6 for (const byte of new Uint8Array(buffer)) binary += String.fromCharCode(byte);
7 return btoa(binary);
8}
9
10// Sender: encrypt the results object and send the ciphertext as Base64 text.
11const results = { test_name: 'pregnancy', results: 'positive', notes: 'You are having twins!' };
12const encrypted = cryptoModule.encrypt(JSON.stringify(results));
13
14await pubnub.publish({
15 channel: 'test-results',
show all 27 lines1struct TestResults: Codable, Equatable {
2 let testName: String
3 let results: String
4 let notes: String
5
6 enum CodingKeys: String, CodingKey {
7 case testName = "test_name"
8 case results
9 case notes
10 }
11}
12
13// Both sides create the same standalone module with the same cipher key.
14let cryptoModule = CryptoModule.aesCbcCryptoModule(with: "pubnubenigma")
15
show all 45 lines1// Both sides create the same standalone module with the same cipher key.
2CryptoModule cryptoModule = CryptoModule.createAesCbcCryptoModule("pubnubenigma", true);
3
4// Sender: encrypt the results object and send the ciphertext as Base64 text.
5JsonObject results = new JsonObject();
6results.addProperty("test_name", "pregnancy");
7results.addProperty("results", "positive");
8results.addProperty("notes", "You are having twins!");
9byte[] encrypted = cryptoModule.encrypt(results.toString().getBytes(StandardCharsets.UTF_8));
10
11JsonObject aps = new JsonObject();
12aps.addProperty("alert", "Your test results are available.");
13JsonObject pnApns = new JsonObject();
14pnApns.add("aps", aps);
15JsonObject message = new JsonObject();
show all 33 linesThe 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:
1{
2 "pn_apns": {
3 "aps": {
4 "alert": "Your test results are available.",
5 "sound" : "bingbong.aiff"
6 }
7 },
8 "results": {
9 "test_name": "pregnancy",
10 "results": "positive",
11 "notes": "You are having twins!"
12 }
13}
Encrypt only the results object with the standalone CryptoModule, as shown in Encrypt a field and decrypt it on the receiver, then put the Base64 text in the payload in place of the object.
After encryption:
1{
2 "pn_apns": {
3 "aps": {
4 "alert": "Your test results are available.",
5 "sound" : "bingbong.aiff"
6 }
7 },
8 "results": "UE5FRAFBQ1JIEAEUspEt4SaiAQxmx+weao+/JtzL1W440jYF66t4u6CkEEuhNspuS0BKSOTvx7FP7UDk+eX6/T2yNVYNfes9SwYjoyU435r9HX3BWvoJExErLlsWx/++dz1kLndrt9QhXw=="
9}
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.