S3ClientSideEncryptionSymMasterKey.java - AWS Code Sample


S3ClientSideEncryptionSymMasterKey.java demonstrates how to upload and download encrypted objects using S3 with a client-side symmetric master key.

/** * Copyright 2018-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * This file is licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. A copy of * the License is located at * * http://aws.amazon.com/apache2.0/ * * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. */ import com.amazonaws.AmazonServiceException; import com.amazonaws.SdkClientException; import com.amazonaws.auth.profile.ProfileCredentialsProvider; import com.amazonaws.regions.Regions; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3EncryptionClientBuilder; import com.amazonaws.services.s3.model.*; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.io.*; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; public class S3ClientSideEncryptionSymMasterKey { public static void main(String[] args) throws Exception { Regions clientRegion = Regions.DEFAULT_REGION; String bucketName = "*** Bucket name ***"; String objectKeyName = "*** Object key name ***"; String masterKeyDir = System.getProperty("java.io.tmpdir"); String masterKeyName = "secret.key"; // Generate a symmetric 256-bit AES key. KeyGenerator symKeyGenerator = KeyGenerator.getInstance("AES"); symKeyGenerator.init(256); SecretKey symKey = symKeyGenerator.generateKey(); // To see how it works, save and load the key to and from the file system. saveSymmetricKey(masterKeyDir, masterKeyName, symKey); symKey = loadSymmetricAESKey(masterKeyDir, masterKeyName, "AES"); try { // Create the Amazon S3 encryption client. EncryptionMaterials encryptionMaterials = new EncryptionMaterials(symKey); AmazonS3 s3EncryptionClient = AmazonS3EncryptionClientBuilder.standard() .withCredentials(new ProfileCredentialsProvider()) .withEncryptionMaterials(new StaticEncryptionMaterialsProvider(encryptionMaterials)) .withRegion(clientRegion) .build(); // Upload a new object. The encryption client automatically encrypts it. byte[] plaintext = "S3 Object Encrypted Using Client-Side Symmetric Master Key.".getBytes(); s3EncryptionClient.putObject(new PutObjectRequest(bucketName, objectKeyName, new ByteArrayInputStream(plaintext), new ObjectMetadata())); // Download and decrypt the object. S3Object downloadedObject = s3EncryptionClient.getObject(bucketName, objectKeyName); byte[] decrypted = com.amazonaws.util.IOUtils.toByteArray(downloadedObject.getObjectContent()); // Verify that the data that you downloaded is the same as the original data. System.out.println("Plaintext: " + new String(plaintext)); System.out.println("Decrypted text: " + new String(decrypted)); } catch (AmazonServiceException e) { // The call was transmitted successfully, but Amazon S3 couldn't process // it, so it returned an error response. e.printStackTrace(); } catch (SdkClientException e) { // Amazon S3 couldn't be contacted for a response, or the client // couldn't parse the response from Amazon S3. e.printStackTrace(); } } private static void saveSymmetricKey(String masterKeyDir, String masterKeyName, SecretKey secretKey) throws IOException { X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(secretKey.getEncoded()); FileOutputStream keyOutputStream = new FileOutputStream(masterKeyDir + File.separator + masterKeyName); keyOutputStream.write(x509EncodedKeySpec.getEncoded()); keyOutputStream.close(); } private static SecretKey loadSymmetricAESKey(String masterKeyDir, String masterKeyName, String algorithm) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException { // Read the key from the specified file. File keyFile = new File(masterKeyDir + File.separator + masterKeyName); FileInputStream keyInputStream = new FileInputStream(keyFile); byte[] encodedPrivateKey = new byte[(int) keyFile.length()]; keyInputStream.read(encodedPrivateKey); keyInputStream.close(); // Reconstruct and return the master key. return new SecretKeySpec(encodedPrivateKey, "AES"); } }

Sample Details

Service: s3

Last tested: 2019-01-28

Author: AWS

Type: full-example