Skip to main content

Overview

AES-256-GCM is our primary encryption mechanism for securing sensitive API communications.

Key Features

  • 256-bit encryption key for strong security
  • 96-bit initialization vector (IV) for GCM mode
  • 128-bit authentication tag for integrity verification
  • Base64URL encoding for safe transmission

Key Exchange Process

  1. 256-bit AES key and 96-bit IV are generated by us
  2. Keys are securely shared with the client
  3. Both the parties use the same key-IV pair for encryption/decryption

Implementation Examples

Encryption (Client-side)

import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class PFMEncryption {

    public static String encryptPayload(String jsonPayload, String key, String iv) {
        try {
            // Decode the Base64 encoded key and IV
            byte[] encryptionKey = Base64.getDecoder().decode(key);
            byte[] encryptionIv = Base64.getDecoder().decode(iv);

            // Convert JSON to bytes
            byte[] plaintextBytes = jsonPayload.getBytes("UTF-8");

            // Setup AES-GCM encryption
            SecretKeySpec keySpec = new SecretKeySpec(encryptionKey, "AES");
            GCMParameterSpec gcmSpec = new GCMParameterSpec(128, encryptionIv);

            Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmSpec);

            // Encrypt and encode
            byte[] encryptedBytes = cipher.doFinal(plaintextBytes);
            return Base64.getUrlEncoder().withoutPadding().encodeToString(encryptedBytes);

        } catch (Exception e) {
            throw new RuntimeException("Encryption failed: " + e.getMessage(), e);
        }
    }
}

Decryption (Client-side)

import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class PFMDecryption {

    public static String decryptResponse(String ciphertext, String key, String iv) {
        try {
            // Decode the Base64 encoded key and IV
            byte[] encryptionKey = Base64.getDecoder().decode(key);
            byte[] encryptionIv = Base64.getDecoder().decode(iv);

            // Decode the encrypted response
            byte[] encryptedBytes = Base64.getUrlDecoder().decode(ciphertext);

            // Setup AES-GCM decryption
            SecretKeySpec keySpec = new SecretKeySpec(encryptionKey, "AES");
            GCMParameterSpec gcmSpec = new GCMParameterSpec(128, encryptionIv);

            Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
            cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmSpec);

            // Decrypt and return
            byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
            return new String(decryptedBytes, "UTF-8");

        } catch (javax.crypto.AEADBadTagException e) {
            throw new RuntimeException("Authentication tag verification failed! Wrong key, IV, or corrupted data.", e);
        } catch (IllegalArgumentException e) {
            throw new RuntimeException("Invalid Base64URL format in ciphertext.", e);
        } catch (Exception e) {
            throw new RuntimeException("Decryption failed: " + e.getMessage(), e);
        }
    }
}

Security Best Practices

Key Management

  • Keys are generated using cryptographically secure random number generators
  • Regular key rotation is recommended
  • Keys should be stored securely and never logged or transmitted in plain text
  • Client can place a request with us to generate new keys

Implementation Guidelines

  • Always validate the authentication tag during decryption
  • Use proper error handling to avoid information leakage
  • Implement secure key storage mechanisms