Encrypt data uploaded to S3 using AWS SDK for Java / SSE-KMS

** Upload / download / bulk delete data to S3 using Amazon S3 Client Builder with AWS SDK for Java ** Upload for server-side encryption It is a method to correspond. If you write the conclusion first, ** When using AmazonS3ClientBuilder, the same description as for AmazonS3Client is OK **.

There are various types of S3 data encryption methods, but here, "SSE-KMS ”Will be taken up.

0. Types of S3 data encryption

There are two main types: server-side encryption (SSE) and client-side encryption (CSE).

The former is a method in which the data sent from the client is received on the server side and then encrypted and saved in the storage, and the latter is a method in which the data is encrypted and sent to the server side before being sent from the client. However, when using server-side encryption, it is necessary to use HTTPS to connect to the endpoint and encrypt the communication path with SSL / TLS, so raw data does not flow over the Internet anyway. ..

Each is further divided into several methods, but CSE is not covered here.

Of these, in the SSE-KMS used this time,

there is.

1. Preparation / Issuing CMK (key) and setting policy for S3 bucket (only if necessary)

If you want to issue a CMK explicitly, use the IAM "Encryption Key" menu. s3_enc_1.jpg In the screen above, ① (ARN) is used when setting the bucket policy, and ② (key ID) is used when specifying the encryption key ID in the Java code.

Don't forget to grant permissions so that the user who uses S3 access can use this key. s3_enc_2.jpg

If you don't explicitly issue a CMK and use the default encryption key, you don't need to do this.

Then, if you want to enforce encryption on upload, set a bucket policy. s3_enc_3.jpg To limit the encryption key to be used, write "," at the end of the 13th line and the 14th line. This description is not necessary if you do not want to limit it (force encryption only) or if you want to use the default encryption key.

2. Change Java code

Modify the sample code in Previous article. There is no change after "Download" (you do not need to specify encryption when downloading).

S3Access.java (first half only)


package s3test;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import com.amazonaws.ClientConfiguration;
import com.amazonaws.Protocol;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder.EndpointConfiguration;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.DeleteObjectsRequest;
import com.amazonaws.services.s3.model.DeleteObjectsRequest.KeyVersion;
import com.amazonaws.services.s3.model.DeleteObjectsResult;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.SSEAwsKeyManagementParams;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.S3ObjectInputStream;

public class S3Access {

    private static final String ENDPOINT_URL = "https://s3-ap-northeast-1.amazonaws.com";
    private static final String REGION       = "ap-northeast-1";
    private static final String ACCESS_KEY   = "【access key】";
    private static final String SECRET_KEY   = "[Secret key]";
    private static final String KMS_KEY_ID   = "[KMS key ID] * Insert the part ②";

    //--------------------------------------------------
    //upload
    //--------------------------------------------------
    public void putObject(String bucketName, String objectKey, int objectSize, InputStream is) throws Exception {

        //Client generation
        AmazonS3 client = getClient(bucketName);

        ObjectMetadata metadata = new ObjectMetadata();
        //Set only the size just in case (Exception if inconsistent)
        metadata.setContentLength(objectSize);

        //upload
        PutObjectRequest putRequest = new PutObjectRequest(bucketName, objectKey, is, metadata)
                                    .withSSEAwsKeyManagementParams(new SSEAwsKeyManagementParams(KMS_KEY_ID));
        client.putObject(putRequest);
        client.putObject(bucketName, objectKey, is, metadata);
    }

If you want to use the default encryption key, write ** * .withSSEAwsKeyManagementParams () * with no arguments in * PutObjectRequest *.

3. Precautions

The content described in the request header at the time of upload differs depending on the type (method) of encryption explained briefly above. Therefore, ** When enforcing encryption with a bucket policy, it is necessary to describe it according to the type of encryption. ** **

When using SSE-S3, please refer to the following.

** Protecting your data with server-side encryption (SSE-S3) with an Amazon S3-managed encryption key /UsingServerSideEncryption.html) ** ** Specifying server-side encryption using the AWS SDK for Java **

If you make a mistake in the correspondence between the bucket policy and the Java code, an upload error will occur.

** The method of using SSE-S3 and the method of using the default encryption key in SSE-KMS are different **, so please be careful not to confuse them.

** [2017.7.6 postscript] ** Using an access key for authentication is not secure, so the following article shows how to change to using EC2 IAM Role.

** Accessing S3 buckets using SSE-KMS encryption in EC2 IAM Role environment (AWS SDK for Java) **

Recommended Posts

Encrypt data uploaded to S3 using AWS SDK for Java / SSE-KMS
Upload / download / bulk delete data to S3 using Amazon S3 Client Builder with AWS SDK for Java
Try Spark Submit to EMR using AWS SDK for Java
Access S3 buckets using SSE-KMS encryption in an EC2 IAM Role environment (AWS SDK for Java)
I tried to operate SQS using AWS Java SDK
AWS SDK for Java 1.11.x and 2.x
Get a list of S3 files with ListObjectsV2Request (AWS SDK for Java)
[AWS SDK for Java] Set a retry policy on the S3 client
Set a signed cookie (for CloudFront) with a custom policy using the AWS SDK for Java
Get S3 object size with AWS SDK for Ruby
Credentials referenced by the AWS SDK for Java by default
Investigated how to call services with Watson SDK for Java
Java for beginners, data hiding
Three JDKs to consider when using Java for free for commercial use
[Rails] How to upload images to AWS S3 using Carrierwave and fog-aws
[Rails] How to upload images to AWS S3 using refile and refile-s3
How to make a groundbreaking diamond using Java for statement wwww
Note: Image storage using AWS S3
Encrypt using RSA cryptography in Java
Deleting AWS S3 Objects in Java
Using Java with AWS Lambda-Eclipse Preparation
[Java] Try to implement using generics
Renamed folders in AWS S3 (Java)
Try using Hyperledger Iroha's Java SDK
How to deploy to AWS using NUXTJS official S3 and CloudFront? With docker-compose