UsingClientSideEncryption
Protecting Data Using Client-Side Encryption
Client-side encryption is the act of encrypting data before sending it to Amazon S3. To enable client-side encryption, you have the following options:
- Use a customer master key (CMK) stored in AWS Key Management Service (AWS KMS).
- Use a master key you store within your application.
The following AWS SDKs support client-side encryption:
Option 1: Using a CMK Stored in AWS KMS
- When uploading an object—Using the customer master key (CMK) ID, the client first sends a request to AWS KMS for a CMK that it can use to encrypt your object data. AWS KMS returns two versions of a randomly generated data key:
- A plaintext version of the data key that the client uses to encrypt the object data
- A cipher blob of the same data key that the client uploads to Amazon S3 as object metadata
Note
The client obtains a unique data key for each object that it uploads.
- When downloading an object—The client downloads the encrypted object from Amazon S3 along with the cipher blob version of the data key stored as object metadata. The client then sends the cipher blob to AWS KMS to get the plaintext version of the data key so that it can decrypt the object data.
For more information about AWS KMS, see What is AWS Key Management Service? in the AWS Key Management Service Developer Guide.
Example
The following example uploads an object to Amazon S3 using AWS KMS with the AWS SDK for Java. The example uses an AWS managed CMK to encrypt data on the client side before uploading it to Amazon S3. If you already have a CMK, you can use that by specifying the value of the kms_cmk_id
variable in the sample code. If you don't have a CMK, or you need another one, you can generate one through the Java API. The example shows how to generate a CMK.
For instructions on creating and testing a working sample, see Testing the Amazon S3 Java Code Examples.
Option 2: Using a Master Key Stored Within Your Application
This section shows how to use a master key stored within your application for client-side data encryption.
Important
Your client-side master keys and your unencrypted data are never sent to AWS. It's important that you safely manage your encryption keys. If you lose them, you can't decrypt your data.
This is how it works:
When uploading an object—You provide a client-side master key to the Amazon S3 encryption client. The client uses the master key only to encrypt the data encryption key that it generates randomly. The process works like this:
The Amazon S3 encryption client generates a one-time-use symmetric key (also known as a data encryption key or data key) locally. It uses the data key to encrypt the data of a single Amazon S3 object. The client generates a separate data key for each object.
The client encrypts the data encryption key using the master key that you provide. The client uploads the encrypted data key and its material description as part of the object metadata. The client uses the material description to determine which client-side master key to use for decryption.
The client uploads the encrypted data to Amazon S3 and saves the encrypted data key as object metadata (
x-amz-meta-x-amz-key
) in Amazon S3.
When downloading an object—The client downloads the encrypted object from Amazon S3. Using the material description from the object's metadata, the client determines which master key to use to decrypt the data key. The client uses that master key to decrypt the data key and then uses the data key to decrypt the object.
The client-side master key that you provide can be either a symmetric key or a public/private key pair. The following examples show how to use both types of keys.
For more information, see Client-Side Data Encryption with the AWS SDK for Java and Amazon S3 .
Note
If you get a cipher-encryption error message when you use the encryption API for the first time, your version of the JDK may have a Java Cryptography Extension (JCE) jurisdiction policy file that limits the maximum key length for encryption and decryption transformations to 128 bits. The AWS SDK requires a maximum key length of 256 bits. To check your maximum key length, use the getMaxAllowedKeyLength()
method of the javax.crypto.Cipher
class. To remove the key-length restriction, install the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files at the Java SE download page.
Example
The following example shows how to do these tasks:
- Generate a 256-bit AES key
- Save and load the AES key to and from the file system
- Use the AES key to encrypt data on the client side before sending it to Amazon S3
- Use the AES key to decrypt data received from Amazon S3
- Verify that the decrypted data is the same as the original data For instructions on creating and testing a working sample, see Testing the Amazon S3 Java Code Examples.
The following example shows how to do these tasks:
- Generate a 1024-bit RSA key pair.
- Save and load the RSA keys to and from the file system.
- Use the RSA keys to encrypt data on the client side before sending it to Amazon S3.
- Use the RSA keys to decrypt data received from Amazon S3.
- Verify that the decrypted data is the same as the original data.
For instructions on creating and testing a working sample, see Testing the Amazon S3 Java Code Examples.