Docs/Encryption

Encryption

Apertur supports end-to-end encrypted uploads using RSA-OAEP key wrapping and AES-256-GCM encryption. Images are encrypted client-side before being sent to the server.

How It Works

The encryption flow uses a hybrid scheme: a random AES-256-GCM symmetric key encrypts the image, and the server's RSA public key wraps the AES key.

  1. Fetch the server's RSA public key from the encryption endpoint.
  2. Generate a random AES-256-GCM key and nonce on the client.
  3. Encrypt the image data with AES-256-GCM.
  4. Wrap the AES key using RSA-OAEP with the server's public key, then upload the ciphertext along with the wrapped key and nonce.

Get Server Key

GET/api/v1/encryption/key

Retrieve the server's RSA public key in PEM format. This key is used to wrap the AES session key.

curl https://api.apertur.ca/api/v1/encryption/key \
  -H "Authorization: Bearer aptr_live_xxxx"

# Response:
# {
#   "publicKey": "-----BEGIN PUBLIC KEY-----\nMIIBI...\n-----END PUBLIC KEY-----"
# }

Encrypted Upload

The Node.js and PHP SDKs handle encryption automatically via imageEncrypted(). For other languages, implement the AES-256-GCM + RSA-OAEP flow manually.

# End-to-end encrypted uploads require client-side encryption.
# Use the Node.js or PHP SDK for automatic encryption handling.
#
# Manual flow:
# 1. GET /api/v1/encryption/key → RSA public key
# 2. Generate a random AES-256-GCM key
# 3. Encrypt the image with AES-256-GCM
# 4. Wrap the AES key with RSA-OAEP using the server's public key
# 5. POST /api/v1/sessions/:id/upload with encrypted payload + wrapped key

Security Note

Encrypted uploads ensure that image data is protected in transit and at rest. The server never sees the raw AES key — only the wrapped version that can be decrypted server-side.

Encryption | API Documentation | Apertur