Server-Side Encryption with Customer-Managed Keys (SSE-C) on WEkEO Elasticity


This guide explains how to encrypt your objects server-side with SSE-C.

Server-side encryption is a way to protecting data at rest. SSE encrypts only the object data. Using server-side encryption with customer-provided encryption keys (SSE-C) allows to set your own keys for encryption. Server manages the encryption as it writes to disks and decryption when you access your objects. The only thing that you must manage is to provide your own encryption keys.

SSE-C is working as on the moment of uploading an object. Server uses the encryption key you provide to apply AES-256 encrytion to data and removes the encryption key from memory. To access the data again you must provide the same encryption key on the request. Server verifies whether provided key matches and then decrypts the object before returning the object data to you.


If you have not used aws before:

$ sudo apt install awscli


$ aws configure

AWS Access Key ID [None]: <your EC2 Access Key>
AWS Secret Access Key [None]: <your EC2 Secret Key>
Default region name [None]: <enter>
Default output format [None]: <enter>

SSE-C at a glance

  • Only HTTPS S3 rejects any requests made over HTTP using SSE-C.

  • If you send request erroneously using HTTP, for security you should discard the key and rotate as appropriate.

  • The ETag in the response is not the MD5 of the object data.

  • You are responsible for managing encryption keys and to which object they were used.

  • If bucket is versioning-enabled, each object version can have its own encryption key.


If you lose encryption key it means the object is also lost. Our servers do not store encryption keys, so it is not possible to access the data again without them.


To encrypt or decrypt objects in SSE-C mode the following headers are required:






Encryption algorithm. Must be set to AES256



256-bit base64-encoded encryption key used in the server-side encryption process



base64-encoded 128-bit MD5 digest of the encryption key according to RFC 1321. It is used to ensure that the encryption has not been corrupted during transport and encoding process.


MD5 digest of the key before base64 encoding.

Headers apply to the following API operations:

  • PutObject

  • PostObject

  • CopyObject (to target objects)

  • HeadObject

  • GetObject

  • InitiateMultipartUpload

  • UploadPart

  • UploadPart-Copy (to target parts)

Example No 1 Generate header values

key=$(echo -n $secret | base64)
keymd5=$(echo -n $secret | openssl dgst -md5 -binary | base64)


openssl rand 32 > sse-c.key
key=$(cat sse-c.key | base64)
keymd5=$(cat sse-c.key | openssl dgst -md5 -binary | base64)

Example No 2 aws-cli (s3api)

Upload an object with SSE-C encryption enabled

aws s3api put-object \
  --bucket bucket-name --key object-name \
  --body contents.txt \
  --sse-customer-algorithm AES256 \
  --sse-customer-key $key \
  --sse-customer-key-md5 $keymd5 \

Example No 3 aws-cli (s3)

aws s3 cp file.txt s3://bucket-name/ \
  --sse-c-key $secret \
  --sse-c AES256 \

Example No 4 aws-cli (s3 blob)

aws s3 cp file.txt s3://bucket/ \
--sse-c-key fileb://sse-c.key \
--sse-c AES256 \


At the moment s3cmd does not support SSE-C encryption.

Downloading the encrypted object

aws s3api get-object <file_name> --bucket <bucket_name> \
 --key <object_key> \
 --sse-customer-key $secret \
 --sse-customer-algorithm AES256 \


aws s3api get-object <file_name> --bucket <bucket_name> \
 --key <object_key> \
 --sse-customer-key fileb://<key_name> \
 --sse-customer-algorithm AES256 \