Encrypting data with SSE-C

Last change on 2024-12-06 • Created on 2024-10-30 • ID: ST-B9E67

You can use SSE-C ("Server-Side Encryption with Customer-provided keys") when you upload new data, and tell the S3 service to encrypt the data with a key that you provide. To decrypt and view the file after it was uploaded, you have to provide the same key again. SSE-C does not encrypt metadata.

Note that the S3 service does not save the key. After the data was encrypted, the S3 service discards the key. If you lose your key, you can no longer access any data that was previously encrypted with it.

The commands depend on the S3-compatible tool you're using. This how-to explains each step with example commands for the MinIO Client and the AWS CLI.

  1. Generate a random 32-byte key for encryption

    For the MinIO Client, the key is created in hexadecimal form is stored in a new file.

    For the AWS CLI, the key is converted from its hexadecimal form to binary form and stored in a new file.

    # MinIO Client
    echo $(openssl rand -hex 32) > ~/enc.key
    
    # AWS CLI
    echo $(openssl rand -hex 32) | xxd -r -p > ~/enc.key

  1. Store the new key permanently

    If you use the key to encrypt data and you lose that key, you can NO LONGER decrypt the data. So make sure you store the key in a safe place!

    View the key:

    # MinIO Client
    cat ~/enc.key
    
    # AWS CLI
    xxd -p ~/enc.key | tr -d '\n'

    Copy the key in hexadecimal form from the output and store the key somewhere safe.


  1. Store the new key as environment variable

    In the steps below, we will provide the key as an environment variable. Create the respective variable now:

    • Create the key as temporary environment variable:

      # MinIO Client
      export KEY="$(cat ~/enc.key)"
      
      # AWS CLI
      export KEY="$HOME/enc.key"

    • Create the key as permanent environment variable:

      # MinIO Client
      echo 'export KEY="$(cat ~/enc.key)"' >> ~/.bashrc
      
      # AWS CLI
      echo 'export KEY="$HOME/enc.key"' >> ~/.bashrc

      Reload the configuration:

      source ~/.bashrc

  1. Upload and encrypt data

    • MinIO Client

      When you upload a new file, you have to add the encryption key with the --enc-c flag.

      # Upload and encrypt a single file
      mc cp example-file.txt <alias_name>/<bucket_name>/example-file.txt \
         --enc-c <alias_name>/=$KEY
      
      # Upload several files at once and encrypt all of them
      mc cp file-1.txt file-2.txt  file-3.txt \
         <alias_name>/<bucket_name> \
         --enc-c <alias_name>/=$KEY
      
      # Upload several files at once and encrypt only selected files
      ## Option 1 - Encryption flag for specific files
      mc cp file-1.txt file-2.txt file-3.txt \
         <alias_name>/<bucket_name> \
         --enc-c <alias_name>/<bucket_name>/file-1.txt=$KEY \
         --enc-c <alias_name>/<bucket_name>/file-2.txt=$KEY
      
      ## Option 2 - Encryption flag for specific prefix
      mc cp <prefix> file-3.txt \
         <alias_name>/<bucket_name> \
         --recursive \
         --enc-c <alias_name>/<bucket_name>/<prefix>/=$KEY

      Option 2 uses the following directory tree:

      <directory>/
      ├─ <prefix>/
      │  ├─ file-1.txt
      │  └─ file-2.txt
      └─ file-3.txt

    • AWS CLI

      # Upload and encrypt a single file
      aws s3 cp example-file.txt s3://<bucket_name>/example.txt \
          --sse-c AES256 \
          --sse-c-key fileb://$KEY
      
      # Upload several files from the same directory at once and encrypt all of them
      aws s3 cp <directory_path> s3://<bucket_name>/ \
          --recursive \
          --sse-c AES256 \
          --sse-c-key fileb://$KEY

  1. View and download encrypted data

    To view or download encrypted data, you have to provide the same key you used for decryption.

    • MinIO Client

      # View
      mc cat <alias_name>/<bucket_name>/example-file.txt \
         --enc-c <alias_name>/=$KEY
      
      # Download
      mc cp <alias_name>/<bucket_name>/example-file.txt example-file.txt \
         --enc-c <alias_name>/=$KEY

    • AWS CLI

      # View
      aws s3 cp s3://<bucket_name>/example-file.txt - \
          --sse-c AES256 \
          --sse-c-key fileb://$KEY
      
      # Download
      aws s3 cp s3://<bucket_name>/example-file.txt example-file.txt \
          --sse-c AES256 \
          --sse-c-key fileb://$KEY

You should now be able to add encrypted data to your Bucket.


Next: