AWS S3 plugin

Blockdaemon provides a plugin for the AWS S3 SDKs for performing easy client-side encryption. This relies on the client-side encryption features offered by AWS.

The SDK is available on different platforms, but here we showcase the Java version.

Security model

In terms of the AWS S3 documentation our plugin works with "option 2: Using a master key stored within your application", meaning that AWS has no access to any encryption keys.

Our plugin works by keeping a master key inside the TSM and use this to derive a unique key for each object in a bucket. The software running on the client will have access to these object-specific keys, but never the master key which never leaves the TSM.

We have the following in play:

  • an AWS bucket with a number of different objects
  • a master key stored inside the TSM
  • a object specific key for each object
  • a nonce for each object which is stored together with the object as metadata

To encrypt and decrypt data the AWS S3 SDK is given a handle to call the Blockdaemon Builder Vault TSM. To get an object-specific key, the SDK will call the TSM with the MasterKeyID and nonce as inputs. This will yield a AES key which is then used by the SDK to encrypt or decrypt the object.

Usage

To use the plugin simply configure the client software as shown here we assume that an S3 bucket and a TSM is at hand.

First we configure the Blockdaemon Builder Vault TSM:

this.s3Bucket = "<< S3 Bucket >>";
Node[] nodes = new Node[3];
nodes[0] = Node.CreateURL("<< Sepior MPC Node 1 >>", PasswordAuthenticator.Create("<< Sepior MPC Node 1 Username>>", "<< Sepior MPC Node 1 Password>>"));
nodes[1] = Node.CreateURL("<< Sepior MPC Node 2 >>", PasswordAuthenticator.Create("<< Sepior MPC Node 2 Username>>", "<< Sepior MPC Node 2 Password>>"));
nodes[2] = Node.CreateURL("<< Sepior MPC Node 3 >>", PasswordAuthenticator.Create("<< Sepior MPC Node 3 Username>>", "<< Sepior MPC Node 3 Password>>"));
TSMClient tsmClient = TSMClient.Create(nodes);

Then we calculate a master key:

String masterKeyId = tsmClient.generatePRFKey();

And finally we setup the S3 encryption client:

this.tkmsEncryptionMaterialProvider = new TKMSEncryptionMaterialProvider(tsmClient, masterKeyId);
CryptoConfiguration cryptoConfig = new CryptoConfiguration().withCryptoMode(CryptoMode.EncryptionOnly);
s3EncryptionClient = AmazonS3EncryptionClientBuilder.standard()
        .withCryptoConfiguration(cryptoConfig)
        .withEncryptionMaterials(this.tkmsEncryptionMaterialProvider)
        .build();