S3ClientSideEncryptionAsymmetricMasterKey.java - AWS Code Sample


S3ClientSideEncryptionAsymmetricMasterKey.java demonstrates how to upload and download encrypted objects using S3 with a client-side asymmetric 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 com.amazonaws.util.IOUtils; import java.io.*; import java.security.*; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; public class S3ClientSideEncryptionAsymmetricMasterKey { public static void main(String[] args) throws Exception { Regions clientRegion = Regions.DEFAULT_REGION; String bucketName = "*** Bucket name ***"; String objectKeyName = "*** Key name ***"; String rsaKeyDir = System.getProperty("java.io.tmpdir"); String publicKeyName = "public.key"; String privateKeyName = "private.key"; // Generate a 1024-bit RSA key pair. KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance("RSA"); keyGenerator.initialize(1024, new SecureRandom()); KeyPair origKeyPair = keyGenerator.generateKeyPair(); // To see how it works, save and load the key pair to and from the file system. saveKeyPair(rsaKeyDir, publicKeyName, privateKeyName, origKeyPair); KeyPair keyPair = loadKeyPair(rsaKeyDir, publicKeyName, privateKeyName, "RSA"); try { // Create the encryption client. EncryptionMaterials encryptionMaterials = new EncryptionMaterials(keyPair); AmazonS3 s3EncryptionClient = AmazonS3EncryptionClientBuilder.standard() .withCredentials(new ProfileCredentialsProvider()) .withEncryptionMaterials(new StaticEncryptionMaterialsProvider(encryptionMaterials)) .withRegion(clientRegion) .build(); // Create a new object. byte[] plaintext = "S3 Object Encrypted Using Client-Side Asymmetric Master Key.".getBytes(); S3Object object = new S3Object(); object.setKey(objectKeyName); object.setObjectContent(new ByteArrayInputStream(plaintext)); ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentLength(plaintext.length); // Upload the object. The encryption client automatically encrypts it. PutObjectRequest putRequest = new PutObjectRequest(bucketName, object.getKey(), object.getObjectContent(), metadata); s3EncryptionClient.putObject(putRequest); // Download and decrypt the object. S3Object downloadedObject = s3EncryptionClient.getObject(bucketName, object.getKey()); byte[] decrypted = 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 saveKeyPair(String dir, String publicKeyName, String privateKeyName, KeyPair keyPair) throws IOException { PrivateKey privateKey = keyPair.getPrivate(); PublicKey publicKey = keyPair.getPublic(); // Write the public key to the specified file. X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKey.getEncoded()); FileOutputStream publicKeyOutputStream = new FileOutputStream(dir + File.separator + publicKeyName); publicKeyOutputStream.write(x509EncodedKeySpec.getEncoded()); publicKeyOutputStream.close(); // Write the private key to the specified file. PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey.getEncoded()); FileOutputStream privateKeyOutputStream = new FileOutputStream(dir + File.separator + privateKeyName); privateKeyOutputStream.write(pkcs8EncodedKeySpec.getEncoded()); privateKeyOutputStream.close(); } private static KeyPair loadKeyPair(String dir, String publicKeyName, String privateKeyName, String algorithm) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { // Read the public key from the specified file. File publicKeyFile = new File(dir + File.separator + publicKeyName); FileInputStream publicKeyInputStream = new FileInputStream(publicKeyFile); byte[] encodedPublicKey = new byte[(int) publicKeyFile.length()]; publicKeyInputStream.read(encodedPublicKey); publicKeyInputStream.close(); // Read the private key from the specified file. File privateKeyFile = new File(dir + File.separator + privateKeyName); FileInputStream privateKeyInputStream = new FileInputStream(privateKeyFile); byte[] encodedPrivateKey = new byte[(int) privateKeyFile.length()]; privateKeyInputStream.read(encodedPrivateKey); privateKeyInputStream.close(); // Convert the keys into a key pair. KeyFactory keyFactory = KeyFactory.getInstance(algorithm); X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedPublicKey); PublicKey publicKey = keyFactory.generatePublic(publicKeySpec); PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedPrivateKey); PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec); return new KeyPair(publicKey, privateKey); } }

Sample Details

Service: s3

Last tested: 2019-01-28

Author: AWS

Type: full-example