Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

How do I use SSE C encryption on NodeJS? I tried the below but got an error

s3.putObject({
  Bucket: 'mybucket',
  Body: 'Hello S3',
  ACL: 'private',
  Key: 'test.txt',
  SSECustomerAlgorithm: 'AES256',
  SSECustomerKey: '0699Exxxxxx'
}, (err) => {
  if (err) return console.error(err.stack)
  s3.getSignedUrl('getObject', {
    Key: 'test.txt',
    Expires: 60,
    SSECustomerAlgorithm: 'AES256',
    SSECustomerKey: '0699Exxxxxx'
  }, (err, data) => {
    if (err) return console.error(err.stack)
    console.log(data)
  })
})

Problem is I get "The secret key was invalid for the specified algorithm"

sails> (node:4802) DeprecationWarning: Calling an asynchronous function without callback is deprecated.
InvalidArgument: The secret key was invalid for the specified algorithm.
    at Request.extractError (/home/jiewmeng/Dropbox/goldbell-server/node_modules/aws-sdk/lib/services/s3.js:538:35)
    at Request.callListeners (/home/jiewmeng/Dropbox/goldbell-server/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
    at Request.emit (/home/jiewmeng/Dropbox/goldbell-server/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
    at Request.emit (/home/jiewmeng/Dropbox/goldbell-server/node_modules/aws-sdk/lib/request.js:668:14)
    at Request.transition (/home/jiewmeng/Dropbox/goldbell-server/node_modules/aws-sdk/lib/request.js:22:10)
    at AcceptorStateMachine.runTo (/home/jiewmeng/Dropbox/goldbell-server/node_modules/aws-sdk/lib/state_machine.js:14:12)
    at /home/jiewmeng/Dropbox/goldbell-server/node_modules/aws-sdk/lib/state_machine.js:26:10
    at Request.<anonymous> (/home/jiewmeng/Dropbox/goldbell-server/node_modules/aws-sdk/lib/request.js:38:9)
    at Request.<anonymous> (/home/jiewmeng/Dropbox/goldbell-server/node_modules/aws-sdk/lib/request.js:670:12)
    at Request.callListeners (/home/jiewmeng/Dropbox/goldbell-server/node_modules/aws-sdk/lib/sequential_executor.js:115:18)
    at Request.emit (/home/jiewmeng/Dropbox/goldbell-server/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
    at Request.emit (/home/jiewmeng/Dropbox/goldbell-server/node_modules/aws-sdk/lib/request.js:668:14)
    at Request.transition (/home/jiewmeng/Dropbox/goldbell-server/node_modules/aws-sdk/lib/request.js:22:10)
    at AcceptorStateMachine.runTo (/home/jiewmeng/Dropbox/goldbell-server/node_modules/aws-sdk/lib/state_machine.js:14:12)
    at /home/jiewmeng/Dropbox/goldbell-server/node_modules/aws-sdk/lib/state_machine.js:26:10
    at Request.<anonymous> (/home/jiewmeng/Dropbox/goldbell-server/node_modules/aws-sdk/lib/request.js:38:9)
    at Request.<anonymous> (/home/jiewmeng/Dropbox/goldbell-server/node_modules/aws-sdk/lib/request.js:670:12)
    at Request.callListeners (/home/jiewmeng/Dropbox/goldbell-server/node_modules/aws-sdk/lib/sequential_executor.js:115:18)
    at callNextListener (/home/jiewmeng/Dropbox/goldbell-server/node_modules/aws-sdk/lib/sequential_executor.js:95:12)
    at IncomingMessage.onEnd (/home/jiewmeng/Dropbox/goldbell-server/node_modules/aws-sdk/lib/event_listeners.js:211:11)
    at emitNone (events.js:91:20)
    at IncomingMessage.emit (events.js:185:7)

Whats wrong? They key I tried using was generated like:

➜  openssl enc -d -a -md sha1 -aes-256-cbc -nosalt -p
enter aes-256-cbc decryption password:
key=0699EC90A02...
iv =433BFB13C10...

I used the key for SSECustomerKey

like image 704
Jiew Meng Avatar asked Nov 29 '16 15:11

Jiew Meng


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 action does the S3 master key perform in the SSE-S3 encryption and decryption process?

Server-Side Encryption with Amazon S3-Managed Keys (SSE-S3) As an additional safeguard, it encrypts the key itself with a root key that it regularly rotates. Amazon S3 server-side encryption uses one of the strongest block ciphers available, 256-bit Advanced Encryption Standard (AES-256) GCM, to encrypt your data.


1 Answers

Try generating your key this way:

const ssecKey = Buffer.alloc(32, 'your key')

Then you can use it like

s3.putObject({
  Bucket: 'mybucket',
  Body: 'Hello S3',
  ACL: 'private',
  Key: 'test.txt',
  SSECustomerAlgorithm: 'AES256',
  SSECustomerKey: ssecKey
}, (err) => {
  if (err) return console.error(err.stack)

  s3.getSignedUrl('getObject', {
    Key: 'test.txt',
    Expires: 60,
    SSECustomerAlgorithm: 'AES256',
    SSECustomerKey: ssecKey
  }, (err, data) => {
    if (err) return console.error(err.stack)

    console.log(data)
  })
})
like image 132
riza Avatar answered Sep 30 '22 19:09

riza