S3 Encryption Concepts

Münir Karslı
3 min readJan 1, 2021

There two stage about data protection. These stages are transit (as it travels to and from Amazon S3) and storage(while it is stored on Amazon S3 infrastructure). As a best practice, all sensitive data stored in Amazon S3 should be encrypted, both at storage and in transit.

For protecting the data in transit, developers can use Amazon S3 SSL API endpoints. For data stored on Amazon S3 infrastructure, developers can encrypt it using different options of Server-Side Encryption (SSE). Your objects in Amazon S3 are encrypted at the object level as they are written to disk in the data centers and then decrypted for you when you access the objects using AES-256.

Developers can also use client-side encryption, which encrypt the objects before uploading to Amazon S3 and then decrypt them after they have downloaded them.

On this article we will examine client-side encryption.

Step By Step Encryption The Data

We will use some Aws services for balancing the performance and security. In the first stage we will use a client-side master key.

  1. The first step is generating a data key. A data key is can generated by the Amazon S3 encryption client locally.
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");         keyGenerator.init(256);

2. The data key generated in step 1 is used to encrypt the data.

String s3ObjectKey = "EncryptedContent2.txt";         
String s3ObjectContent = "This is the 2nd content to encrypt";

AmazonS3EncryptionV2 s3Encryption =
AmazonS3EncryptionClientV2Builder.standard()
.withRegion(Regions.DEFAULT_REGION)
.withClientConfiguration(new ClientConfiguration())
.withCryptoConfiguration(new CryptoConfigurationV2()
.withCryptoMode(CryptoMode.AuthenticatedEncryption))
.withEncryptionMaterialsProvider(new
StaticEncryptionMaterialsProvider(new
EncryptionMaterials(secretKey)))
.build();

3. The data key is then encrypted with a key-encrypting key unique to the service storing your data. The client uploads the encrypted data key and its material description as part of the object metadata. The material description helps the client later determine which client-side master key to use for decryption.

4. Finally, The encrypted data key as object metadata and the encrypted data are uploaded to S3.

s3Encryption.putObject(bucket_name, s3ObjectKey, s3ObjectContent);

By similar methods you can use AWS KMS managed customer master key. This process is similar to the process described earlier for using KMS-SSE

// Generate a KMS keymaterialProvider = new KMSEncryptionMaterialsProvider(kms_cmk_id);encryptionClient = new AmazonS3EncryptionClient(
new ProfileCredentials Provider(),
materialProvider,
new CryptoConfiguration().withKmsRegion(Regions.US_EAST_1)) .withRegion(Region.getRegion(Regions.US_EAST_1));
//Generate a content and put it to S3byte[] plaintext = "Hello World, S3 Client-side Encryption Using Asymmetric Master Key!".getBytes();encryptionClient.putObject(
new PutObjectRequest(bucketName,
objectKey,
new ByteArrayInputStream(plaintext),
new ObjectMetadata()));
// Download the object.S3Object downloadedObject = encryptionClient.getObject(bucketName, objectKey);byte[] decrypted = IOUtils.toByteArray(downloadedObject .getObjectContent());

--

--