Skip to main content

Encrypt Data with KEM

This guide walks you through encrypting data using Qpher hybrid KEM-DEM encryption, which combines Kyber768 post-quantum key encapsulation with AES-256-GCM symmetric encryption.

Prerequisites

  • A Qpher account with an active API key
  • At least one active Kyber768 key pair (see Key Management)
  • The key_version of the active key you want to use

How Qpher KEM Encryption Works

Qpher uses a hybrid KEM-DEM (Key Encapsulation Mechanism - Data Encapsulation Mechanism) scheme:

  1. KEM step: Kyber768 encapsulates a shared secret using your public key
  2. KDF step: HKDF-SHA256 derives a 256-bit symmetric key from the shared secret
  3. DEM step: AES-256-GCM encrypts your plaintext with the derived key

The shared secret is never stored or returned. Your private key never leaves the Qpher secure enclave.

1088B
KEM Ciphertext (1088B)IV (Nonce) (12B)AES Ciphertext (21B)Auth Tag (16B)
Total: 1137 bytes (overhead + plaintext)

Step 1: Prepare Your Plaintext

Your plaintext must be base64-encoded before sending it to the API.

Base64 Encoding Required

All plaintext data must be base64-encoded in the request body. The API will reject raw binary or unencoded strings. Maximum plaintext size is 1 MB (1,048,576 bytes) before encoding.

Step 2: Send the Encrypt Request

POST/api/v1/kem/encryptEncrypt plaintext using Kyber768 hybrid KEM-DEM
Encrypt Data
curl -X POST https://api.qpher.ai/api/v1/kem/encrypt \
  -H "Content-Type: application/json" \
  -H "x-api-key: qph_your_key_here" \
  -d '{
    "plaintext": "SGVsbG8sIFdvcmxkIQ==",
    "key_version": 1
  }'

Step 3: Understand the Response

RequestPOST/api/v1/kem/encrypt
Content-Type: application/json
x-api-key: qph_your_key_here
{
  "plaintext": "SGVsbG8sIFdvcmxkIQ==",
  "key_version": 1
}
Response200
{
  "data": {
    "ciphertext": "base64-encoded-ciphertext...",
    "key_version": 1,
    "algorithm": "Kyber768"
  },
  "request_id": "550e8400-e29b-41d4-a716-446655440000",
  "timestamp": "2026-02-15T10:30:00Z"
}
FieldDescription
ciphertextBase64-encoded ciphertext containing the KEM ciphertext, IV, AES ciphertext, and auth tag
key_versionThe key version used for encryption — store this alongside the ciphertext
algorithmThe KEM algorithm used (Kyber768)
request_idUnique request identifier for tracing and support
Store the key_version

Always store the key_version alongside the ciphertext. You will need the exact same key_version to decrypt the data later. There is no implicit "latest" key — Qpher requires explicit versioning on every operation.

Error Handling

HTTP StatusError CodeCauseResolution
400ERR_INVALID_001Missing or invalid plaintext or key_versionEnsure plaintext is valid base64 and key_version is a positive integer
400ERR_KEM_001Plaintext exceeds 1 MB limitSplit data into smaller chunks
401ERR_AUTH_001Invalid or missing API keyCheck your x-api-key header
404ERR_KEM_003Key version not foundVerify the key_version exists for your tenant
409ERR_KEM_004Key is not in active statusOnly active keys can encrypt — generate or rotate to get a new active key
429ERR_RATE_001Rate limit exceededReduce request frequency or upgrade your plan