How to use AWS SDK for Java for encryption with MinIO Server 
aws-sdk for Java is the official AWS SDK for Java. In this recipe we will learn how to use aws-sdk for Java for encryption on MinIO server using both Symmetric and Asymmetric approach.
Encryption allows additional security layer for sensitive user data (images, audio clips, etc.) stored on MinIO server.
Prerequisites
Install aws-sdk for Java from the official AWS SDK docs here.
Symmetric Encryption
Symmetric Encryption uses single key for both encryption and decryption. Following are the steps involved for Symmetric Encryption using AES :
1. Generate AES key
Use Java KeyGenrator class for generating 256 bit AES key.
//Generate symmetric 256 bit AES key.
KeyGenerator symKeyGenerator = KeyGenerator.getInstance("AES");
symKeyGenerator.init(256);
SecretKey symKey = symKeyGenerator.generateKey();
2. Create AWS S3 encryption client using generated key.
EncryptionMaterials encryptionMaterials = new EncryptionMaterials(
mySymmetricKey);
// Add MinIO server accessKey and secretKey
AWSCredentials credentials = new BasicAWSCredentials(
"USWUXHGYZQYFYFFIT3RE", "MOJRH0mkL1IPauahWITSVvyDrQbEEIwljvmxdq03");
// Create encryption client with MinIO server as endpoint
AmazonS3EncryptionClient encryptionClient = new AmazonS3EncryptionClient(
credentials, new StaticEncryptionMaterialsProvider(
encryptionMaterials));
Region usEast1 = Region.getRegion(Regions.US_EAST_1);
encryptionClient.setRegion(usEast1);
encryptionClient.setEndpoint("http://localhost:9000");
3. Operations on MinIO using AWS S3 encryption client
Use the encryption client created in previous steps to perform operations on MinIO server.
// Create the bucket
encryptionClient.createBucket(bucketName);
// Upload object using the encryption client.
byte[] plaintext = "Hello World, S3 Client-side Encryption Using Asymmetric Master Key!"
.getBytes();
System.out.println("plaintext's length: " + plaintext.length);
encryptionClient.putObject(new PutObjectRequest(bucketName, objectKey,
new ByteArrayInputStream(plaintext), new ObjectMetadata()));
4. Test
Once the object is downloaded, check if the decrypted object is same as the plaintext object uploaded to the server.
// Download the object
S3Object downloadedObject = encryptionClient.getObject(bucketName,
objectKey);
byte[] decrypted = IOUtils.toByteArray(downloadedObject
.getObjectContent());
// Verify same data.
Assert.assertTrue(Arrays.equals(plaintext, decrypted));
Complete working code for Symmetric AES encryption can be found here
Asymmetric Encryption
Asymmetric Encryption uses public key and private key for encryption and decryption. Following are the steps involved for Asymmetric Encryption using RSA :
1. Generate RSA key
// Generate RSA key pair
KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance(algorithm);
keyGenerator.initialize(1024, srand);
keyGenerator.generateKeyPair();
2. Create AWS S3 encryption client using generated key.
EncryptionMaterials encryptionMaterials = new EncryptionMaterials(
loadedKeyPair);
// Add MinIO server accessKey and secretKey
AWSCredentials credentials = new BasicAWSCredentials("USWUXHGYZQYFYFFIT3RE",
"MOJRH0mkL1IPauahWITSVvyDrQbEEIwljvmxdq03");
// Create encryption client with MinIO server as endpoint
AmazonS3EncryptionClient encryptionClient = new AmazonS3EncryptionClient(
credentials, new StaticEncryptionMaterialsProvider(encryptionMaterials));
Region usEast1 = Region.getRegion(Regions.US_EAST_1);
encryptionClient.setRegion(usEast1);
encryptionClient.setEndpoint("http://localhost:9000");
3. Operations on MinIO using AWS S3 encryption client
Use the encryption client created in previous steps to perform operations on MinIO server.
// Create the bucket
encryptionClient.createBucket(bucketName);
// Upload the object.
byte[] plaintext = "Hello World, S3 Client-side Encryption Using Asymmetric Master Key!"
.getBytes();
System.out.println("plaintext's length: " + plaintext.length);
encryptionClient.putObject(new PutObjectRequest(bucketName, objectKey,
new ByteArrayInputStream(plaintext), new ObjectMetadata()));
4. Test
Once the object is downloaded, check if the decrypted object is same as the plaintext object uploaded to the server.
// Download the object
S3Object downloadedObject = encryptionClient.getObject(bucketName,
objectKey);
byte[] decrypted = IOUtils.toByteArray(downloadedObject
.getObjectContent());
Assert.assertTrue(Arrays.equals(plaintext, decrypted));
// Verify same data.
System.out.println("decrypted length: " + decrypted.length);
Complete working code for Asymmetric RSA encryption can be found here
Note: When MinIO generates a presignedURL it would be generated for an encrypted object. So, downloading this object through other methods like curl you would get an encrypted object. This is because curl has no awareness of encryption details.