Amazon Simple Storage Service
Developer Guide (API Version 2006-03-01)
« PreviousNext »
View the PDF for this guide.Go to the AWS Discussion Forum for this product.Go to the Kindle Store to download this guide in Kindle format.Did this page help you?  Yes | No |  Tell us about it...

Customizing Your Client-Side Encryption Environment

Client-side encryption using the AWS SDK for Java gives you several options for customizing your encryption/decryption process. This topic discusses how to configure common options and what they mean.

You can configure your client-side encryption environment by choosing the appropriate constructor of the AmazonS3EncryptionClient class. The constructor has several signatures and can take a combination of the following four arguments: AWSCredentials, ClientConfiguration, EncryptionMaterials, and CryptoConfiguration. The AWSCredentials and ClientConfiguration arguments are the same arguments that are used in the non-encrypted Amazon S3 client AmazonS3Client and are not discussed here. The remaining two arguments, EncryptionMaterials and CryptoConfiguration allow you to customize different aspects of your client-side encryption and are discussed below. For more information about the encryption client constructors, see the AWS Java SDK documentation.

Specifying Encryption Materials

To use Amazon S3 client-side encryption, you must specify a key that is used in the encryption process, for both the upload and retrieval of encrypted data. You must keep this key secure.

Important

Your private encryption keys and your unencrypted data are never sent to AWS; therefore, if you lose your encryption keys, you won't be able to unencrypt your data.

You can use the EncryptionMaterials class to indicate to the Amazon S3 encryption client what key you want to use for encryption. You can specify either an asymmetric or symmetric key to use; however, it is recommended that you use an asymmetric key whenever possible. An asymmetric key is a key pair that consists of a public key and a private key.

The following code snippet demonstrates how to create a new key pair (asymmetric key). For an example of how to read and write the key pair to file, see Example: Encrypted Upload to Amazon S3 Using a Key Pair.

// Create a new asymmetric key.
KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance(encryptionAlgorithm);
keyGenerator.initialize(4096, new SecureRandom());
KeyPair keyPair = keyGenerator.generateKeyPair();

// Construct an instance of AmazonS3EncryptionClient.
AWSCredentials credentials = new BasicAWSCredentials(myAccessKeyId, mySecretKey);

// Create an EncryptionMaterials object using the symmetric key.
EncryptionMaterials encryptionMaterials = new EncryptionMaterials(keyPair);

// Create a new encryption client.
AmazonS3EncryptionClient encryptedS3Client = 
	new AmazonS3EncryptionClient(credentials, encryptionMaterials);

The following code snippet demonstrates how to create a new symmetric key. For an example of how to read and write the symmetric key to file, see Example: Creating a 256-bit AES Secret.

// Create a new symmetric key.
KeyGenerator symKeyGenerator = KeyGenerator.getInstance("DES");
SecretKey symKey = symKeyGenerator.generateKey();

// Construct an instance of AmazonS3EncryptionClient.
AWSCredentials credentials = new BasicAWSCredentials(myAccessKeyId, mySecretKey);

// Create an EncryptionMaterials object using the symmetric key.
EncryptionMaterials encryptionMaterials = new EncryptionMaterials(symKey);

// Create a new encryption client.
AmazonS3EncryptionClient encryptedS3Client = 
	new AmazonS3EncryptionClient(credentials, encryptionMaterials);

Specifying Encryption Metadata Storage Location

When the Amazon S3 client (using the AmazonS3EncryptionClient class) encrypts data and uploads it to Amazon S3, the encrypted envelope symmetric key is also stored in S3. By default, the encrypted key is stored as user-defined object metadata. After you upload an encrypted object, you can view its properties and see the additional metadata name-value pairs related to encryption. For example, the key name x-amz-meta-x-amz-key and key value equal to the envelope key are set on an client-side encrypted object uploaded to Amazon S3.

Optionally, you can also choose to store encryption metadata as an instruction file stored at the same location as the encrypted file. The instruction file will have the same key name as the encrypted data file but with the extension ".instruction" appended. You should use an instruction file when the strength of your encryption key results in a symmetric key that is too big for the object metadata. Metadata should be less than 2 KB. Encryption metadata is either stored as object metadata or an instruction file, but not both.

The following code sample demonstrates how to store encryption metadata in an instruction file using the CryptoConfiguration class and the appropriate constructor of the AmazonS3EncryptionClient class.

// Load the asymmetric key pair.
KeyPair myKeyPair = S3ClientSideEncryptionTest.LoadKeyPair(pathToKey, encrytionAlgorithm);

// Construct an instance of AmazonS3EncryptionClient.
AWSCredentials credentials = new BasicAWSCredentials(myAccessKeyId, mySecretKey);
EncryptionMaterials encryptionMaterials = new EncryptionMaterials(myKeyPair);

// Create an instance of the CryptoConfiguration class to specify using the instruction file.
CryptoConfiguration cryptoConfig = 
    new CryptoConfiguration().withStorageMode(CryptoStorageMode.InstructionFile);

// Use the CryptoConfiguration instance in the encryption client constructor.
AmazonS3EncryptionClient encryptedS3 = 
	new AmazonS3EncryptionClient(credentials, encryptionMaterials, cryptoConfig);

// Upload the object.
encryptedS3.putObject(new PutObjectRequest(bucketName, key, createSampleFile()));
 
// Retrieve the object.
S3Object downloadedObject = encryptedS3.getObject(bucketName, key);

Specifying A Crypto Provider

The default cryptography provider used in Amazon S3 client-side encryption client is the Java Cryptography Extension (JCE). Optionally, you can specify a different cryptography provider implementation to use to encrypt and decrypt data.

The following example sample code demonstrates using the Bouncy Castle provider.

// Create a new instance of the provider.
Provider bcProvider = new BouncyCastleProvider();

// Load the asymmetric key pair.
KeyPair myKeyPair = S3ClientSideEncryptionTest.LoadKeyPair(pathToKey, encrytionAlgorithm);

// Construct an instance of AmazonS3EncryptionClient.
AWSCredentials credentials = new BasicAWSCredentials(myAccessKeyId, mySecretKey);
EncryptionMaterials encryptionMaterials = new EncryptionMaterials(myKeyPair);

// Create an instance of the CryptoConfiguration class to specify a crypto provider.
CryptoConfiguration cryptoConfig = 
    new CryptoConfiguration().withCryptoProvider(bcProvider);

// Use the CryptoConfiguration instance in the encryption client constructor.
AmazonS3EncryptionClient encryptedS3 = 
	new AmazonS3EncryptionClient(credentials, encryptionMaterials, cryptoConfig);

// Upload the object.
encryptedS3.putObject(new PutObjectRequest(bucketName, key, createSampleFile()));
 
// Retrieve the object.
S3Object downloadedObject = encryptedS3.getObject(bucketName, key);