Server-Side Encryption with Customer-Managed Keys (SSE-C) on 3Engines Cloud[🔗](#server-side-encryption-with-customer-managed-keys-sse-c-on-brand-name "Permalink to this headline") ===================================================================================================================================================================================== Introduction[🔗](#introduction "Permalink to this headline") ----------------------------------------------------------- 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 encryption 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. Requirements[🔗](#requirements "Permalink to this headline") ----------------------------------------------------------- * A bucket ([How to use Object Storage on 3Engines Cloud](How-to-use-Object-Storage-on-3Engines-Cloud.html.md)) * A user with the required access rights on the bucket * EC2 credentials ([How to generate and manage EC2 credentials on 3Engines Cloud](../cloud/How-to-generate-ec2-credentials-on-3Engines-Cloud.html.md)) * Have installed and configured aws If you have not used aws before: ``` $ sudo apt install awscli ``` Then: ``` $ aws configure AWS Access Key ID [None]: AWS Secret Access Key [None]: Default region name [None]: Default output format [None]: ``` **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. Attention 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. REST API[🔗](#rest-api "Permalink to this headline") --------------------------------------------------- To encrypt or decrypt objects in SSE-C mode the following headers are required: | Header | Type | Description | | --- | --- | --- | | x-amz-server-side​-encryption​-customer-algorithm | string | Encryption algorithm. Must be set to AES256 | | x-amz-server-side​-encryption​-customer-key | string | 256-bit base64-encoded encryption key used in the server-side encryption process | | x-amz-server-side​-encryption​-customer-key-MD5 | string | base64-encoded 128-bit MD5 digest of the encryption key according to [RFC 1321](https://www.rfc-editor.org/rfc/rfc1321). It is used to ensure that the encryption has not been corrupted during transport and encoding process. | Note 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[🔗](#example-no-1-generate-header-values "Permalink to this headline") --------------------------------------------------------------------------------------------------------- ``` secret="32bytesOfTotallyRandomCharacters" key=$(echo -n $secret | base64) keymd5=$(echo -n $secret | openssl dgst -md5 -binary | base64) ``` OR ``` 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)[🔗](#example-no-2-aws-cli-s3api "Permalink to this headline") ----------------------------------------------------------------------------------------- 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 \ --endpoint-url https://s3.waw3-1.3Engines.com ``` Example No 3 aws-cli (s3)[🔗](#example-no-3-aws-cli-s3 "Permalink to this headline") ----------------------------------------------------------------------------------- ``` aws s3 cp file.txt s3://bucket-name/ \ --sse-c-key $secret \ --sse-c AES256 \ --endpoint https://s3.waw3-1.3Engines.com ``` Example No 4 aws-cli (s3 blob)[🔗](#example-no-4-aws-cli-s3-blob "Permalink to this headline") --------------------------------------------------------------------------------------------- ``` aws s3 cp file.txt s3://bucket/ \ --sse-c-key fileb://sse-c.key \ --sse-c AES256 \ --endpoint https://s3.waw3-1.3Engines.com ``` Note At the moment **s3cmd** does not support SSE-C encryption. Downloading the encrypted object[🔗](#downloading-the-encrypted-object "Permalink to this headline") --------------------------------------------------------------------------------------------------- ``` aws s3api get-object --bucket \ --key \ --sse-customer-key $secret \ --sse-customer-algorithm AES256 \ --endpoint https://s3.waw3-1.3Engines.com ``` or ``` aws s3api get-object --bucket \ --key \ --sse-customer-key fileb:// \ --sse-customer-algorithm AES256 \ --endpoint https://s3.waw3-1.3Engines.com ```