Object Storage Server-Side Encryption with Customer-Provided Keys
What is SSE-C?
SSE-C (Server-Side Encryption with Customer-Provided Keys) is an encryption option for object storage where you supply the encryption key for each request. The object storage service uses your key to encrypt data when writing and to decrypt it when reading. The service does not store your key; it is used only for the duration of the request. The objects stored in the bucket are encrypted at rest using AES-256.
How it works
Upload (PUT)
You generate a 256-bit key, send it (and its MD5, as base64) in the request headers. The service encrypts the object with that key and stores only the ciphertext. The key is not stored.Download (GET)
You send the same key (and algorithm/MD5) in the request. The service decrypts the object and returns the plaintext. Without the correct key, the request fails.Copy
For copying an SSE-C object (e.g. within the same or another bucket), you provide the source object’s key for decryption and, if the copy target is also SSE-C, a (possibly new) key for encryption.
The standard algorithm used is AES-256. The key is sent as base64, and the MD5 of the key (also base64) is sent so the service can verify key integrity.
Key management
- Generate keys securely (e.g.
openssl rand 32for a 256-bit key). - Store keys in a secure, durable place (e.g. secrets manager, HSM). Losing the key means losing access to the data.
- Restrict access to keys to the same level as the data they protect.
- Rotate keys if required by policy; rotation typically means re-uploading or copying objects with a new key and then retiring the old key.
Example: upload and download with SSE-C
The script below uses the AWS CLI (S3-compatible) against Thalassa Cloud object storage. It:
- Creates a small test file.
- Generates a 256-bit key and its base64/MD5 values.
- Uploads an object with SSE-C (AES256).
- Downloads the same object by supplying the same key.
Replace <YOUR BUCKET NAME> with your bucket name. Ensure your CLI is configured with valid Thalassa Cloud object storage credentials and endpoint.
Also configure your Object Storage access credentials (key and secret).
#!/bin/bash
ENDPOINT="https://objects.nl-01.thalassa.cloud"
REGION="nl-01"
BUCKET="<YOUR BUCKET NAME>"
OBJECT="sse-c-demo.txt"
echo "Creating test file..."
echo "Hello SSE-C $(date -u +"%Y-%m-%dT%H:%M:%SZ")" > hello.txt
echo "Generating 256-bit encryption key..."
openssl rand -out sse.key 32
SSE_KEY=$(base64 < sse.key | tr -d '\n')
SSE_KEY_MD5=$(openssl md5 -binary sse.key | base64 | tr -d '\n')
echo "Uploading object with SSE-C..."
aws --no-cli-pager --region "$REGION" --endpoint-url "$ENDPOINT" s3api put-object \
--bucket "$BUCKET" \
--key "$OBJECT" \
--body hello.txt \
--sse-customer-algorithm AES256 \
--sse-customer-key "$SSE_KEY" \
--sse-customer-key-md5 "$SSE_KEY_MD5"
echo "Downloading object (must provide same key)..."
aws --no-cli-pager --region "$REGION" --endpoint-url "$ENDPOINT" s3api get-object \
--bucket "$BUCKET" \
--key "$OBJECT" \
downloaded.txt \
--sse-customer-algorithm AES256 \
--sse-customer-key "$SSE_KEY" \
--sse-customer-key-md5 "$SSE_KEY_MD5"
echo
echo "Downloaded content:"
cat downloaded.txt
echo
echo "Done."
echo "⚠ If you lose the encryption key, the object cannot be recovered."Required headers for SSE-C with the S3 API:
- Upload:
x-amz-server-side-encryption-customer-algorithm: AES256,x-amz-server-side-encryption-customer-key(base64),x-amz-server-side-encryption-customer-key-MD5(base64). - Download: Same three headers so the service can decrypt the object.