Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use S3 SSE C (Server Side Encryption with Client Provided Keys) with Ruby

I'm trying to upload a file to S3 and have it encrypted using the SSE-C encryption options. I can upload without the SSE-C options, but when I supply the sse_customer_key options I'm getting the following error:

ArgumentError: header x-amz-server-side-encryption-customer-key has field value "QkExM0JGRTNDMUUyRDRCQzA5NjAwNEQ2MjRBNkExMDYwQzBGQjcxODJDMjM0\nnMUE2MTNENDRCOTcxRjA2Qzk1Mg=", this cannot include CR/LF

I'm not sure if the problem is with the key I'm generating or with the encoding. I've played around with different options here, but the AWS documentation is not very clear. In the general SSE-C documentation it says you need to supply a x-amz-server-side​-encryption​-customer-key header, which is described as this:

Use this header to provide the 256-bit, base64-encoded encryption key for Amazon S3 to use to encrypt or decrypt your data.

However, if I look at the Ruby SDK documentation for uploading a file the 3 options have a slightly different description

  • :sse_customer_algorithm (String) — Specifies the algorithm to use to when encrypting the object (e.g.,
  • :sse_customer_key (String) — Specifies the customer-provided encryption key for Amazon S3 to use in
  • :sse_customer_key_md5 (String) — Specifies the 128-bit MD5 digest of the encryption key according to RFC

(I didn't copy that wrong, the AWS documentation is literally half-written like that)

So the SDK documentation makes it seem like you supply the raw sse_customer_key and that it would base64-encode it on your behalf (which makes sense to me).

So right now I'm building the options like this:

  sse_customer_algorithm: :AES256,
  sse_customer_key: sse_customer_key,
  sse_customer_key_md5: Digest::MD5.hexdigest(sse_customer_key)

I previously tried doing Base64.encode64(sse_customer_key) but that gave me a different error:

Aws::S3::Errors::InvalidArgument: The secret key was invalid for the specified algorithm

I'm not sure if I'm generating the key incorrectly or if I'm supplying the key incorrectly (or if it's a different problem altogether).

This is how I'm generating the key:

require "openssl"
OpenSSL::Cipher.new("AES-256-CBC").random_key
like image 387
Jaco Pretorius Avatar asked Sep 18 '19 13:09

Jaco Pretorius


People also ask

Can S3 protect data at rest using client-side encryption?

Data protection refers to protecting data while in-transit (as it travels to and from Amazon S3) and at rest (while it is stored on disks in Amazon S3 data centers). You can protect data in transit using Secure Socket Layer/Transport Layer Security (SSL/TLS) or client-side encryption.

Which header should be included when you are using SSE-S3 encryption?

The header value must be "AES256". Use this header to provide the 256-bit, base64-encoded encryption key for Amazon S3 to use to encrypt or decrypt your data.

What does the server-side encryption option an Amazon S3 provide?

Amazon S3 Server Side Encryption (SSE) enables you to easily encrypt data stored at rest in Amazon S3. Using Amazon S3 SSE, you can encrypt data simply by adding an additional request header when writing the object to Amazon S3. Decryption happens automatically when data is retrieved.

What is the difference between SSE-S3 and SSE KMS?

Server-Side Encryption with AWS KMS keys (SSE-KMS) is similar to SSE-S3, but with some additional benefits and charges for using this service. There are separate permissions for the use of a KMS key that provides added protection against unauthorized access of your objects in Amazon S3.


1 Answers

Oh, did you notice that your key contains '\n'? That's most probably why you get the CR/LF error: QkExM0JGRTNDMUUyRDRCQzA5NjAwNEQ2MjRBNkExMDYwQzBGQjcxODJDMjM0(\n)nMUE2MTNENDRCOTcxRjA2Qzk1Mg=

As mentioned by the colleague in the comments, strict_encode64 is an option, as it complies to RFC 2045.

By the way, I got this insight from here: https://bugs.ruby-lang.org/issues/14664

Hope it helps! :)

like image 92
Fabio Manzano Avatar answered Nov 14 '22 23:11

Fabio Manzano