Amazon S3 Encryption Client Migration
This topic shows how to migrate your applications from Version 1 (V1) of the Amazon Simple Storage Service (Amazon S3) encryption client to Version 2 (V2) and ensure application availability throughout the migration process.
Migration Overview
This migration happens in two phases:
1. Update existing clients to read new formats. First, deploy an updated version of the AWS SDK for C++ to your application. This allows existing V1 encryption clients to decrypt objects written by the new V2 clients. If your application uses multiple AWS SDKs, you must upgrade each SDK separately.
2. Migrate encryption and decryption clients to V2. Once all of your V1 encryption clients can read new formats, you can migrate your existing encryption and decryption clients to their respective V2 versions.
Update Existing Clients to Read New Formats
You must first update your existing clients to the latest SDK release. After completing this step, your application’s V1 clients will be able to decrypt objects encrypted by V2 encryption clients without updating your application’s code base.
Build and Install the Latest Version of the AWS SDK for C++
Applications Consuming the SDK from Source
If you build and install the AWS SDK for C++ from source, download or clone the SDK source from aws/aws-sdk-cpp
If you are upgrading AWS SDK for C++ from a version earlier than 1.8.x, see this CHANGELOG
Applications Consuming the SDK from Vcpkg
If your application uses Vcpkg
You can run the following command to upgrade package aws-sdk-cpp
:
vcpkg upgrade aws-sdk-cpp
And verify the version of package aws-sdk-cpp
:
vcpkg list aws-sdk-cpp
The version should be at least 1.8.24.
For more information on using Vcpkg with the AWS SDK for C++, see Get the AWS SDK for C++ from a package manager.
Build, Install, and Deploy Your Applications
If your application is statically linking against the AWS SDK for C++, code changes are not required in your application, but you must build your application again to consume the latest SDK changes. This step is not necessary for dynamic linking.
After upgrading your application’s dependency version and verifying application functionality, proceed to deploying your application to your fleet. Once application deployment is complete, you can proceed with the next phase for migrating your application to use the V2 encryption and decryption clients.
Migrate Encryption and Decryption Clients to V2
The following steps show you how to successfully migrate your code from V1 to V2 of the Amazon S3 encryption client. Since code changes are required, you will need to rebuild your application regardless of whether it’s statically or dynamically linking against the AWS SDK for C++.
Using New Encryption Materials
With V2 Amazon S3 encryption clients and the V2 crypto configuration, the following encryption materials have been deprecated:
-
SimpleEncryptionMaterials
-
KMSEncryptionMaterials
They have been replaced with the following secure encryption materials:
-
SimpleEncryptionMaterialsWithGCMAAD
-
KMSWithContextEncryptionMaterials
The following code changes are required to construct a V2 S3 encryption client:
-
- If you are using
KMSEncryptionMaterials
when creating an S3 encryption client: -
-
When creating a V2 S3 encryption client, replace
KMSEncryptionMaterials
withKMSWithContextEncryptionMaterials
and specify it in the V2 crypto configuration. -
When putting an object with V2 Amazon S3 encryption clients, you must explicitly provide a string-string context map as the KMS context for encrypting the CEK. This might be an empty map.
-
- If you are using
-
- If you are using
SimpleEncryptionMaterials
when creating an S3 encryption client: -
-
When creating a V2 Amazon S3 encryption client, replace
SimpleEncryptionMaterials
withSimpleEncryptionMaterialsWithGCMAAD
and specify it in the V2 crypto configuration. -
When putting an object with V2 Amazon S3 encryption clients, you must explicitly provide an empty string-string context map, otherwise the SDK will return an error.
-
- If you are using
Example: Using the KMS/KMSWithContext Key Wrap Algorithm
Pre-migration (KMS key wrap)
auto materials = Aws::MakeShared<KMSEncryptionMaterials>("s3Encryption", CUSTOMER_MASTER_KEY_ID);
CryptoConfiguration cryptoConfig;
S3EncryptionClient encryptionClient(materials, cryptoConfig);
// Code snippet here to setup the putObjectRequest object.
encryptionClient.PutObject(putObjectRequest);
Post-migration (KMSWithContext key wrap)
auto materials = Aws::MakeShared<KMSWithContextEncryptionMaterials>("s3EncryptionV2", CUSTOMER_MASTER_KEY_ID);
CryptoConfigurationV2 cryptoConfig(materials);
S3EncryptionClientV2 encryptionClient(cryptoConfig);
// Code snippet here to setup the putObjectRequest object.
Aws::Map<Aws::String, Aws::String> kmsContextMap;
kmsContextMap.emplace("client", "aws-sdk-cpp");
kmsContextMap.emplace("version", "1.8.0");
encryptionClient.PutObject(putObjectRequest, kmsContextMap /* could be empty as well */);
Example: Using the AES/AES-GCM Key Wrap Algorithm
Pre-migration (AES key wrap)
auto materials = Aws::MakeShared<SimpleEncryptionMaterials>("s3Encryption", HashingUtils::Base64Decode(AES_MASTER_KEY_BASE64));
CryptoConfiguration cryptoConfig;
S3EncryptionClient encryptionClient(materials, cryptoConfig);
// Code snippet here to setup the putObjectRequest object.
encryptionClient.PutObject(putObjectRequest);
Post-migration (AES-GCM key wrap)
auto materials = Aws::MakeShared<SimpleEncryptionMaterialsWithGCMAAD>("s3EncryptionV2", HashingUtils::Base64Decode(AES_MASTER_KEY_BASE64));
CryptoConfigurationV2 cryptoConfig(materials);
S3EncryptionClientV2 encryptionClient(cryptoConfig);
// Code snippet here to setup the putObjectRequest object.
encryptionClient.PutObject(putObjectRequest, {} /* must be an empty map */);
Additional Examples
The following examples demonstrate how to address specific use cases related to a migration from V1 to V2.
Decrypt Objects Encrypted by Legacy Amazon S3 Encryption Clients
By default, you can’t use the V2 Amazon S3 encryption client to decrypt objects that were encrypted with deprecated key wrap algorithms or deprecated content crypto schemas.
The following key wrap algorithms have been deprecated:
-
KMS
-
AES_KEY_WRAP
And the following content crypto schemas have been deprecated:
-
CBC
-
CTR
If you’re using legacy Amazon S3 encryption clients in the AWS SDK for C++ to encrypt the objects, you’re likely using the deprecated methods if:
-
You used
SimpleEncryptionMaterials
orKMSEncryptionMaterials
. -
You used
ENCRYPTION_ONLY
asCrypto Mode
in your crypto configuration.
To use the V2 Amazon S3 encryption client to decrypt objects that were encrypted by deprecated key wrap algorithms or deprecated content
crypto schemas, you must override the default value of SecurityProfile
in the V2 crypto configuration from V2
to V2_AND_LEGACY
.
Example
Pre-migration
auto materials = Aws::MakeShared<KMSEncryptionMaterials>("s3Encryption", CUSTOMER_MASTER_KEY_ID);
CryptoConfiguration cryptoConfig;
S3EncryptionClient encryptionClient(materials, cryptoConfig);
// Code snippet here to setup the getObjectRequest object.
encryptionClient.GetObject(getObjectRequest);
Post-migration
auto materials = Aws::MakeShared<KMSWithContextEncryptionMaterials>("s3EncryptionV2", CUSTOMER_MASTER_KEY_ID);
CryptoConfigurationV2 cryptoConfig(materials);
cryptoConfig.SetSecurityProfile(SecurityProfile::V2_AND_LEGACY);
S3EncryptionClientV2 encryptionClient(cryptoConfig);
// Code snippet here to setup the getObjectRequest object.
encryptionClient.GetObject(getObjectRequest);
Decrypt Objects with Range
With legacy Amazon S3 encryption clients, you can specify a range of bytes to receive when decrypting an S3 object. In the V2 Amazon S3 encryption client, this
feature is DISABLED
by default. Therefore you have to override the default value of RangeGetMode
from DISABLED
to ALL
in the V2 crypto configuration.
Example
Pre-migration
auto materials = Aws::MakeShared<KMSEncryptionMaterials>("s3Encryption", CUSTOMER_MASTER_KEY_ID);
CryptoConfiguration cryptoConfig;
S3EncryptionClient encryptionClient(materials, cryptoConfig);
// Code snippet here to setup the getObjectRequest object.
getObjectRequest.WithRange("bytes=38-75");
encryptionClient.GetObject(getObjectRequest);
Post-migration
auto materials = Aws::MakeShared<KMSWithContextEncryptionMaterials>("s3EncryptionV2", CUSTOMER_MASTER_KEY_ID);
CryptoConfigurationV2 cryptoConfig(materials);
cryptoConfig.SetUnAuthenticatedRangeGet(RangeGetMode::ALL);
S3EncryptionClientV2 encryptionClient(cryptoConfig);
// Code snippet here to setup the getObjectRequest object.
getObjectRequest.WithRange("bytes=38-75");
encryptionClient.GetObject(getObjectRequest);
Decrypt Objects with any CMK
When decrypting objects that were encrypted with KMSWithContextEncryptionMaterials
, V2 Amazon S3 encryption clients are capable
of letting KMS to find the proper CMK by providing an empty master key. This feature is DISABLED
by default. You have
to configure it explicitly by calling SetKMSDecryptWithAnyCMK(true)
for your KMS encryption materials.
Example
Pre-migration
auto materials = Aws::MakeShared<KMSEncryptionMaterials>("s3Encryption", ""/* provide an empty KMS Master Key*/);
CryptoConfiguration cryptoConfig;
S3EncryptionClient encryptionClient(materials, cryptoConfig);
// Code snippet here to setup the getObjectRequest object.
encryptionClient.GetObject(getObjectRequest);
Post-migration
auto materials = Aws::MakeShared<KMSWithContextEncryptionMaterials>("s3EncryptionV2", ""/* provide an empty KMS Master Key*/);
materials.SetKMSDecryptWithAnyCMK(true);
CryptoConfigurationV2 cryptoConfig(materials);
S3EncryptionClientV2 encryptionClient(cryptoConfig);
// Code snippet here to setup the getObjectRequest object.
encryptionClient.GetObject(getObjectRequest);
For complete code for all of these migration scenarios, see the Amazon S3 Encryption
example