

# Security for Amazon SDK for C\$1\$1
<a name="security"></a>

Cloud security at Amazon Web Services (Amazon) is the highest priority. As an Amazon customer, you benefit from a data center and network architecture that is built to meet the requirements of the most security-sensitive organizations. Security is a shared responsibility between Amazon and you. The [Shared Responsibility Model](http://www.amazonaws.cn/compliance/shared-responsibility-model/) describes this as Security of the Cloud and Security in the Cloud.

**Security of the Cloud** – Amazon is responsible for protecting the infrastructure that runs all of the services offered in the Amazon Cloud and providing you with services that you can use securely. Our security responsibility is the highest priority at Amazon, and the effectiveness of our security is regularly tested and verified by third-party auditors as part of the [Amazon Compliance Programs](http://www.amazonaws.cn/compliance/programs/).

**Security in the Cloud** – Your responsibility is determined by the Amazon service you are using, and other factors including the sensitivity of your data, your organization’s requirements, and applicable laws and regulations.

This Amazon product or service follows the [shared responsibility model](http://www.amazonaws.cn/compliance/shared-responsibility-model/) through the specific Amazon Web Services (Amazon) services it supports. For Amazon service security information, see the [Amazon service security documentation page](https://docs.amazonaws.cn/security/?id=docs_gateway#aws-security) and [Amazon services that are in scope of Amazon compliance efforts by compliance program](http://www.amazonaws.cn/compliance/services-in-scope/).

**Topics**
+ [Data Protection](data-protection.md)
+ [Identity and Access Management](security-iam.md)
+ [Compliance Validation](compliance-validation.md)
+ [Resilience](disaster-recovery-resiliency.md)
+ [Infrastructure Security](infrastructure-security.md)
+ [Enforcing a minimum TLS version](enforcing-tls.md)
+ [

# Amazon S3 Encryption Client Migration (V1 to V2)
](s3-encryption-migration-v1-v2.md)
+ [

# Amazon S3 Encryption Client Migration (V2 to V3)
](s3-encryption-migration-v2-v3.md)

# Data Protection in Amazon SDK for C\$1\$1
<a name="data-protection"></a>

The Amazon [shared responsibility model](https://aws.amazon.com/compliance/shared-responsibility-model/) applies to data protection in Amazon SDK for C\$1\$1. As described in this model, Amazon is responsible for protecting the global infrastructure that runs all of the Amazon Web Services Cloud. You are responsible for maintaining control over your content that is hosted on this infrastructure. You are also responsible for the security configuration and management tasks for the Amazon Web Services services that you use. For more information about data privacy, see the [Data Privacy FAQ](https://www.amazonaws.cn/compliance/data-privacy-faq/).

For data protection purposes, we recommend that you protect Amazon Web Services account credentials and set up individual users with Amazon IAM Identity Center or Amazon Identity and Access Management (IAM). That way, each user is given only the permissions necessary to fulfill their job duties. We also recommend that you secure your data in the following ways:
+ Use multi-factor authentication (MFA) with each account.
+ Use SSL/TLS to communicate with Amazon resources. We require TLS 1.2 and recommend TLS 1.3.
+ Set up API and user activity logging with Amazon CloudTrail. For information about using CloudTrail trails to capture Amazon activities, see [Working with CloudTrail trails](https://docs.amazonaws.cn/awscloudtrail/latest/userguide/cloudtrail-trails.html) in the *Amazon CloudTrail User Guide*.
+ Use Amazon encryption solutions, along with all default security controls within Amazon Web Services services.
+ Use advanced managed security services such as Amazon Macie, which assists in discovering and securing sensitive data that is stored in Amazon S3.
+ If you require FIPS 140-3 validated cryptographic modules when accessing Amazon through a command line interface or an API, use a FIPS endpoint. For more information about the available FIPS endpoints, see [Federal Information Processing Standard (FIPS) 140-3](https://www.amazonaws.cn/compliance/fips/).

We strongly recommend that you never put confidential or sensitive information, such as your customers' email addresses, into tags or free-form text fields such as a **Name** field. This includes when you work with SDK for C\$1\$1 or other Amazon Web Services services using the console, API, Amazon CLI, or Amazon SDKs. Any data that you enter into tags or free-form text fields used for names may be used for billing or diagnostic logs. If you provide a URL to an external server, we strongly recommend that you do not include credentials information in the URL to validate your request to that server.

# Identity and Access Management
<a name="security-iam"></a>

Amazon Identity and Access Management (IAM) is an Amazon Web Services service that helps an administrator securely control access to Amazon resources. IAM administrators control who can be *authenticated* (signed in) and *authorized* (have permissions) to use Amazon resources. IAM is an Amazon Web Services service that you can use with no additional charge.

**Topics**
+ [

## Audience
](#security_iam_audience)
+ [

## Authenticating with identities
](#security_iam_authentication)
+ [

## Managing access using policies
](#security_iam_access-manage)
+ [

## How Amazon Web Services services work with IAM
](#security_iam_service-with-iam)
+ [

## Troubleshooting Amazon identity and access
](#security_iam_troubleshoot)

## Audience
<a name="security_iam_audience"></a>

How you use Amazon Identity and Access Management (IAM) differs, depending on the work that you do in Amazon.

**Service user** – If you use Amazon Web Services services to do your job, then your administrator provides you with the credentials and permissions that you need. As you use more Amazon features to do your work, you might need additional permissions. Understanding how access is managed can help you request the right permissions from your administrator. If you cannot access a feature in Amazon, see [Troubleshooting Amazon identity and access](#security_iam_troubleshoot) or the user guide of the Amazon Web Services service you are using.

**Service administrator** – If you're in charge of Amazon resources at your company, you probably have full access to Amazon. It's your job to determine which Amazon features and resources your service users should access. You must then submit requests to your IAM administrator to change the permissions of your service users. Review the information on this page to understand the basic concepts of IAM. To learn more about how your company can use IAM with Amazon, see the user guide of the Amazon Web Services service you are using.

**IAM administrator** – If you're an IAM administrator, you might want to learn details about how you can write policies to manage access to Amazon. To view example Amazon identity-based policies that you can use in IAM, see the user guide of the Amazon Web Services service you are using.

## Authenticating with identities
<a name="security_iam_authentication"></a>

Authentication is how you sign in to Amazon using your identity credentials. You must be authenticated as the Amazon Web Services account root user, an IAM user, or by assuming an IAM role.

For programmatic access, Amazon provides an SDK and CLI to cryptographically sign requests. For more information, see [Amazon Signature Version 4 for API requests](https://docs.amazonaws.cn/IAM/latest/UserGuide/reference_sigv.html) in the *IAM User Guide*.

### Amazon Web Services account root user
<a name="security_iam_authentication-rootuser"></a>

 When you create an Amazon Web Services account, you begin with one sign-in identity called the Amazon Web Services account *root user* that has complete access to all Amazon Web Services services and resources. We strongly recommend that you don't use the root user for everyday tasks. For tasks that require root user credentials, see [Tasks that require root user credentials](https://docs.amazonaws.cn/IAM/latest/UserGuide/id_root-user.html#root-user-tasks) in the *IAM User Guide*. 

### Federated identity
<a name="security_iam_authentication-federated"></a>

As a best practice, require human users to use federation with an identity provider to access Amazon Web Services services using temporary credentials.

A *federated identity* is a user from your enterprise directory, web identity provider, or Amazon Directory Service that accesses Amazon Web Services services using credentials from an identity source. Federated identities assume roles that provide temporary credentials.

### IAM users and groups
<a name="security_iam_authentication-iamuser"></a>

An *[IAM user](https://docs.amazonaws.cn/IAM/latest/UserGuide/id_users.html)* is an identity with specific permissions for a single person or application. We recommend using temporary credentials instead of IAM users with long-term credentials. For more information, see [Require human users to use federation with an identity provider to access Amazon using temporary credentials](https://docs.amazonaws.cn/IAM/latest/UserGuide/best-practices.html#bp-users-federation-idp) in the *IAM User Guide*.

An [https://docs.amazonaws.cn/IAM/latest/UserGuide/id_groups.html](https://docs.amazonaws.cn/IAM/latest/UserGuide/id_groups.html) specifies a collection of IAM users and makes permissions easier to manage for large sets of users. For more information, see [Use cases for IAM users](https://docs.amazonaws.cn/IAM/latest/UserGuide/gs-identities-iam-users.html) in the *IAM User Guide*.

### IAM roles
<a name="security_iam_authentication-iamrole"></a>

An *[IAM role](https://docs.amazonaws.cn/IAM/latest/UserGuide/id_roles.html)* is an identity with specific permissions that provides temporary credentials. You can assume a role by [switching from a user to an IAM role (console)](https://docs.amazonaws.cn/IAM/latest/UserGuide/id_roles_use_switch-role-console.html) or by calling an Amazon CLI or Amazon API operation. For more information, see [Methods to assume a role](https://docs.amazonaws.cn/IAM/latest/UserGuide/id_roles_manage-assume.html) in the *IAM User Guide*.

IAM roles are useful for federated user access, temporary IAM user permissions, cross-account access, cross-service access, and applications running on Amazon EC2. For more information, see [Cross account resource access in IAM](https://docs.amazonaws.cn/IAM/latest/UserGuide/access_policies-cross-account-resource-access.html) in the *IAM User Guide*.

## Managing access using policies
<a name="security_iam_access-manage"></a>

You control access in Amazon by creating policies and attaching them to Amazon identities or resources. A policy defines permissions when associated with an identity or resource. Amazon evaluates these policies when a principal makes a request. Most policies are stored in Amazon as JSON documents. For more information about JSON policy documents, see [Overview of JSON policies](https://docs.amazonaws.cn/IAM/latest/UserGuide/access_policies.html#access_policies-json) in the *IAM User Guide*.

Using policies, administrators specify who has access to what by defining which **principal** can perform **actions** on what **resources**, and under what **conditions**.

By default, users and roles have no permissions. An IAM administrator creates IAM policies and adds them to roles, which users can then assume. IAM policies define permissions regardless of the method used to perform the operation.

### Identity-based policies
<a name="security_iam_access-manage-id-based-policies"></a>

Identity-based policies are JSON permissions policy documents that you attach to an identity (user, group, or role). These policies control what actions identities can perform, on which resources, and under what conditions. To learn how to create an identity-based policy, see [Define custom IAM permissions with customer managed policies](https://docs.amazonaws.cn/IAM/latest/UserGuide/access_policies_create.html) in the *IAM User Guide*.

Identity-based policies can be *inline policies* (embedded directly into a single identity) or *managed policies* (standalone policies attached to multiple identities). To learn how to choose between managed and inline policies, see [Choose between managed policies and inline policies](https://docs.amazonaws.cn/IAM/latest/UserGuide/access_policies-choosing-managed-or-inline.html) in the *IAM User Guide*.

### Resource-based policies
<a name="security_iam_access-manage-resource-based-policies"></a>

Resource-based policies are JSON policy documents that you attach to a resource. Examples include IAM *role trust policies* and Amazon S3 *bucket policies*. In services that support resource-based policies, service administrators can use them to control access to a specific resource. You must [specify a principal](https://docs.amazonaws.cn/IAM/latest/UserGuide/reference_policies_elements_principal.html) in a resource-based policy.

Resource-based policies are inline policies that are located in that service. You can't use Amazon managed policies from IAM in a resource-based policy.

### Access control lists (ACLs)
<a name="security_iam_access-manage-acl"></a>

Access control lists (ACLs) control which principals (account members, users, or roles) have permissions to access a resource. ACLs are similar to resource-based policies, although they do not use the JSON policy document format.

Amazon S3, Amazon WAF, and Amazon VPC are examples of services that support ACLs. To learn more about ACLs, see [Access control list (ACL) overview](https://docs.amazonaws.cn/AmazonS3/latest/userguide/acl-overview.html) in the *Amazon Simple Storage Service Developer Guide*.

### Other policy types
<a name="security_iam_access-manage-other-policies"></a>

Amazon supports additional policy types that can set the maximum permissions granted by more common policy types:
+ **Permissions boundaries** – Set the maximum permissions that an identity-based policy can grant to an IAM entity. For more information, see [Permissions boundaries for IAM entities](https://docs.amazonaws.cn/IAM/latest/UserGuide/access_policies_boundaries.html) in the *IAM User Guide*.
+ **Service control policies (SCPs)** – Specify the maximum permissions for an organization or organizational unit in Amazon Organizations. For more information, see [Service control policies](https://docs.amazonaws.cn/organizations/latest/userguide/orgs_manage_policies_scps.html) in the *Amazon Organizations User Guide*.
+ **Resource control policies (RCPs)** – Set the maximum available permissions for resources in your accounts. For more information, see [Resource control policies (RCPs)](https://docs.amazonaws.cn/organizations/latest/userguide/orgs_manage_policies_rcps.html) in the *Amazon Organizations User Guide*.
+ **Session policies** – Advanced policies passed as a parameter when creating a temporary session for a role or federated user. For more information, see [Session policies](https://docs.amazonaws.cn/IAM/latest/UserGuide/access_policies.html#policies_session) in the *IAM User Guide*.

### Multiple policy types
<a name="security_iam_access-manage-multiple-policies."></a>

When multiple types of policies apply to a request, the resulting permissions are more complicated to understand. To learn how Amazon determines whether to allow a request when multiple policy types are involved, see [Policy evaluation logic](https://docs.amazonaws.cn/IAM/latest/UserGuide/reference_policies_evaluation-logic.html) in the *IAM User Guide*.

## How Amazon Web Services services work with IAM
<a name="security_iam_service-with-iam"></a>

To get a high-level view of how Amazon Web Services services work with most IAM features, see [Amazon services that work with IAM](https://docs.amazonaws.cn/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html) in the *IAM User Guide*.

To learn how to use a specific Amazon Web Services service with IAM, see the security section of the relevant service's User Guide.

## Troubleshooting Amazon identity and access
<a name="security_iam_troubleshoot"></a>

Use the following information to help you diagnose and fix common issues that you might encounter when working with Amazon and IAM.

**Topics**
+ [

### I am not authorized to perform an action in Amazon
](#security_iam_troubleshoot-no-permissions)
+ [

### I am not authorized to perform iam:PassRole
](#security_iam_troubleshoot-passrole)
+ [

### I want to allow people outside of my Amazon Web Services account to access my Amazon resources
](#security_iam_troubleshoot-cross-account-access)

### I am not authorized to perform an action in Amazon
<a name="security_iam_troubleshoot-no-permissions"></a>

If you receive an error that you're not authorized to perform an action, your policies must be updated to allow you to perform the action.

The following example error occurs when the `mateojackson` IAM user tries to use the console to view details about a fictional `my-example-widget` resource but doesn't have the fictional `awes:GetWidget` permissions.

```
User: arn:aws-cn:iam::123456789012:user/mateojackson is not authorized to perform: awes:GetWidget on resource: my-example-widget
```

In this case, the policy for the `mateojackson` user must be updated to allow access to the `my-example-widget` resource by using the `awes:GetWidget` action.

If you need help, contact your Amazon administrator. Your administrator is the person who provided you with your sign-in credentials.

### I am not authorized to perform iam:PassRole
<a name="security_iam_troubleshoot-passrole"></a>

If you receive an error that you're not authorized to perform the `iam:PassRole` action, your policies must be updated to allow you to pass a role to Amazon.

Some Amazon Web Services services allow you to pass an existing role to that service instead of creating a new service role or service-linked role. To do this, you must have permissions to pass the role to the service.

The following example error occurs when an IAM user named `marymajor` tries to use the console to perform an action in Amazon. However, the action requires the service to have permissions that are granted by a service role. Mary does not have permissions to pass the role to the service.

```
User: arn:aws-cn:iam::123456789012:user/marymajor is not authorized to perform: iam:PassRole
```

In this case, Mary's policies must be updated to allow her to perform the `iam:PassRole` action.

If you need help, contact your Amazon administrator. Your administrator is the person who provided you with your sign-in credentials.

### I want to allow people outside of my Amazon Web Services account to access my Amazon resources
<a name="security_iam_troubleshoot-cross-account-access"></a>

You can create a role that users in other accounts or people outside of your organization can use to access your resources. You can specify who is trusted to assume the role. For services that support resource-based policies or access control lists (ACLs), you can use those policies to grant people access to your resources.

To learn more, consult the following:
+ To learn whether Amazon supports these features, see [How Amazon Web Services services work with IAM](#security_iam_service-with-iam).
+ To learn how to provide access to your resources across Amazon Web Services accounts that you own, see [Providing access to an IAM user in another Amazon Web Services account that you own](https://docs.amazonaws.cn/IAM/latest/UserGuide/id_roles_common-scenarios_aws-accounts.html) in the *IAM User Guide*.
+ To learn how to provide access to your resources to third-party Amazon Web Services accounts, see [Providing access to Amazon Web Services accounts owned by third parties](https://docs.amazonaws.cn/IAM/latest/UserGuide/id_roles_common-scenarios_third-party.html) in the *IAM User Guide*.
+ To learn how to provide access through identity federation, see [Providing access to externally authenticated users (identity federation)](https://docs.amazonaws.cn/IAM/latest/UserGuide/id_roles_common-scenarios_federated-users.html) in the *IAM User Guide*.
+ To learn the difference between using roles and resource-based policies for cross-account access, see [Cross account resource access in IAM](https://docs.amazonaws.cn/IAM/latest/UserGuide/access_policies-cross-account-resource-access.html) in the *IAM User Guide*.

# Compliance Validation for this Amazon Product or Service
<a name="compliance-validation"></a>

To learn whether an Amazon Web Services service is within the scope of specific compliance programs, see [Amazon Web Services services in Scope by Compliance Program](https://aws.amazon.com/compliance/services-in-scope/) and choose the compliance program that you are interested in. For general information, see [Amazon Web Services Compliance Programs](https://aws.amazon.com/compliance/programs/).

You can download third-party audit reports using Amazon Artifact. For more information, see [Downloading Reports in Amazon Artifact](https://docs.aws.amazon.com/artifact/latest/ug/downloading-documents.html).

Your compliance responsibility when using Amazon Web Services services is determined by the sensitivity of your data, your company's compliance objectives, and applicable laws and regulations. For more information about your compliance responsibility when using Amazon Web Services services, see [Amazon Security Documentation](https://docs.amazonaws.cn/security/).

This Amazon product or service follows the [shared responsibility model](http://www.amazonaws.cn/compliance/shared-responsibility-model/) through the specific Amazon Web Services (Amazon) services it supports. For Amazon service security information, see the [Amazon service security documentation page](https://docs.amazonaws.cn/security/?id=docs_gateway#aws-security) and [Amazon services that are in scope of Amazon compliance efforts by compliance program](http://www.amazonaws.cn/compliance/services-in-scope/).

# Resilience for this Amazon Product or Service
<a name="disaster-recovery-resiliency"></a>

The Amazon global infrastructure is built around Amazon Web Services Regions and Availability Zones. 

Amazon Web Services Regions provide multiple physically separated and isolated Availability Zones, which are connected with low-latency, high-throughput, and highly redundant networking. 

With Availability Zones, you can design and operate applications and databases that automatically fail over between zones without interruption. Availability Zones are more highly available, fault tolerant, and scalable than traditional single or multiple data center infrastructures. 

For more information about Amazon Regions and Availability Zones, see [Amazon Global Infrastructure](http://www.amazonaws.cn/about-aws/global-infrastructure/).

This Amazon product or service follows the [shared responsibility model](http://www.amazonaws.cn/compliance/shared-responsibility-model/) through the specific Amazon Web Services (Amazon) services it supports. For Amazon service security information, see the [Amazon service security documentation page](https://docs.amazonaws.cn/security/?id=docs_gateway#aws-security) and [Amazon services that are in scope of Amazon compliance efforts by compliance program](http://www.amazonaws.cn/compliance/services-in-scope/).

# Infrastructure Security for this Amazon Product or Service
<a name="infrastructure-security"></a>

This Amazon product or service uses managed services, and therefore is protected by the Amazon global network security. For information about Amazon security services and how Amazon protects infrastructure, see [Amazon Cloud Security](https://www.amazonaws.cn/security/). To design your Amazon environment using the best practices for infrastructure security, see [Infrastructure Protection](https://docs.amazonaws.cn/wellarchitected/latest/security-pillar/infrastructure-protection.html) in *Security Pillar Amazon Well‐Architected Framework*.

You use Amazon published API calls to access this Amazon Product or Service through the network. Clients must support the following:
+ Transport Layer Security (TLS). We require TLS 1.2 and recommend TLS 1.3.
+ Cipher suites with perfect forward secrecy (PFS) such as DHE (Ephemeral Diffie-Hellman) or ECDHE (Elliptic Curve Ephemeral Diffie-Hellman). Most modern systems such as Java 7 and later support these modes.

Additionally, requests must be signed by using an access key ID and a secret access key that is associated with an IAM principal. Or you can use the [Amazon Security Token Service](https://docs.amazonaws.cn/STS/latest/APIReference/Welcome.html) (Amazon STS) to generate temporary security credentials to sign requests.

This Amazon product or service follows the [shared responsibility model](http://www.amazonaws.cn/compliance/shared-responsibility-model/) through the specific Amazon Web Services (Amazon) services it supports. For Amazon service security information, see the [Amazon service security documentation page](https://docs.amazonaws.cn/security/?id=docs_gateway#aws-security) and [Amazon services that are in scope of Amazon compliance efforts by compliance program](http://www.amazonaws.cn/compliance/services-in-scope/).

# Enforcing a minimum TLS version in the Amazon SDK for C\$1\$1
<a name="enforcing-tls"></a>

To increase security when communicating with Amazon services, you should configure SDK for C\$1\$1 to use TLS 1.2 or later. We recommend using TLS 1.3.

The Amazon SDK for C\$1\$1 is a cross-platform library. You can build and run your application on the platforms you want. Different platforms might depend on different underlying HTTP clients.

By default, macOS, Linux, Android and other non-Windows platforms use [libcurl](https://curl.haxx.se/libcurl/). If the libcurl version is later than 7.34.0, TLS 1.0 is the minimum version used by the underlying HTTP clients.

For Windows, the default library is [WinHttp](https://docs.microsoft.com/en-us/windows/win32/winhttp). Windows decides the actual protocol to use among the TLS 1.0, TLS 1.1, TLS 1.2, and TLS 1.3 protocols available. [WinINet](https://docs.microsoft.com/en-us/windows/win32/wininet) and [IXMLHttpRequest2](https://docs.microsoft.com/en-us/windows/win32/api/_ixhr2) are the other two options that are available on Windows. You can configure your application to replace the default library during CMake and at runtime. For these two HTTP clients, Windows also decides the secure protocol.

The Amazon SDK for C\$1\$1 also provides the flexibility to override the default HTTP clients. For example, you can enforce libcurl or use whatever HTTP clients you want by using a custom HTTP client factory. So to use TLS 1.2 as the minimum version, you must be aware of the HTTP client library you’re using.

## Enforce specific TLS version with libcurl on all platforms
<a name="enforce-tls-1-2-with-libcurl-on-all-platforms"></a>

This section assumes that the Amazon SDK for C\$1\$1 is using libcurl as a dependency for HTTP protocol support. To explicitly specify the TLS version, you will need a minimum libcurl version of 7.34.0. In addition, you might need to modify the source code of the Amazon SDK for C\$1\$1 and then rebuild it.

The following procedure shows you how to perform these tasks.

### To enforce TLS 1.2 with libcurl
<a name="to-enforce-tls-1-2-with-libcurl"></a>

1. Verify that your installation of libcurl is at least version 7.34.0.

1. Download the source code for the Amazon SDK for C\$1\$1 from [GitHub](http://github.com/aws/aws-sdk-cpp).

1. Open `aws-cpp-sdk-core/source/http/curl/CurlHttpClient.cpp` and find the following lines of code.

   ```
   #if LIBCURL_VERSION_MAJOR >= 7
   #if LIBCURL_VERSION_MINOR >= 34
   curl_easy_setopt(connectionHandle, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
   #endif //LIBCURL_VERSION_MINOR
   #endif //LIBCURL_VERSION_MAJOR
   ```

1. If necessary, change the last parameter in the function call as follows.

   ```
   #if LIBCURL_VERSION_MAJOR >= 7
   #if LIBCURL_VERSION_MINOR >= 34
   curl_easy_setopt(connectionHandle, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
   #endif //LIBCURL_VERSION_MINOR
   #endif //LIBCURL_VERSION_MAJOR
   ```

1. If you performed the preceding code changes, build and install the Amazon SDK for C\$1\$1 according to the instructions at [https://github.com/aws/aws-sdk-cpp\$1building-the-sdk](https://github.com/aws/aws-sdk-cpp#building-the-sdk).

1. For the service client in your application, enable `verifySSL` in its client configuration, if this option isn’t already enabled.

### To enforce TLS 1.3 with libcurl
<a name="to-enforce-tls-1-3-with-libcurl"></a>

To enforce TLS 1.3, follow the steps in the preceding section setting the `CURL_SSLVERSION_TLSv1_3` option instead of `CURL_SSLVERSION_TLSv1_2`.

## Enforce specific TLS version on Windows
<a name="enforce-tls-1-2-on-windows"></a>

The following procedures show you how to enforce TLS 1.2 or TLS 1.3 with WinHttp, WinINet, or IXMLHTTPRequest2.

### Prerequisite: Determine Windows TLS support
<a name="prerequisite-enable-tls-1-1-and-1-2-on-windows"></a>
+ Determine the TLS protocol version support available for your system as described at [https://docs.microsoft.com/en-us/windows/win32/secauthn/protocols-in-tls-ssl–schannel-ssp-](https://docs.microsoft.com/en-us/windows/win32/secauthn/protocols-in-tls-ssl--schannel-ssp-).
+ If you're running on Windows 7 SP1 or Windows Server 2008 R2 SP1, you need to ensure that TLS 1.2 support is enabled in the registry, as described at [https://docs.microsoft.com/en-us/windows-server/security/tls/tls-registry-settings\$1tls-12](https://docs.microsoft.com/en-us/windows-server/security/tls/tls-registry-settings#tls-12). If you're running an earlier distribution, you must upgrade your operating system. 

### To enforce TLS 1.2 or TLS 1.3 with WinHttp
<a name="to-enforce-tls-1-2-with-winhttp"></a>

WinHttp provides an API to explicitly set the acceptable secure protocols. However, to make this configurable at runtime, you need to modify the source code of the Amazon SDK for C\$1\$1 and then rebuild it.

1. Download the source code for the Amazon SDK for C\$1\$1 from [GitHub](http://github.com/aws/aws-sdk-cpp).

1. Open `aws-cpp-sdk-core/source/http/windows/WinHttpSyncHttpClient.cpp` and find the following lines of code.

   ```
   #if defined(WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_3)
       DWORD flags = WINHTTP_FLAG_SECURE_PROTOCOL_TLS1 | WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1 |
               WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2 | WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_3;
   #else
       DWORD flags = WINHTTP_FLAG_SECURE_PROTOCOL_TLS1 | WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1 | WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2;
   #endif
   
   if (!WinHttpSetOption(GetOpenHandle(), WINHTTP_OPTION_SECURE_PROTOCOLS, &flags, sizeof(flags)))
   {
       AWS_LOGSTREAM_FATAL(GetLogTag(), "Failed setting secure crypto protocols with error code: " << GetLastError());
   }
   ```

   The `WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_3` option flag is defined if TLS 1.3 is present on the current build system. For more information, see [WINHTTP\$1OPTION\$1SECURE\$1PROTOCOLS](https://learn.microsoft.com/en-us/windows/win32/winhttp/option-flags#winhttp_option_secure_protocols) and [TLS protocol version support](https://learn.microsoft.com/en-us/windows/win32/secauthn/protocols-in-tls-ssl--schannel-ssp-#tls-protocol-version-support) on the Microsoft website.

1. Choose one of the following:
   + **To enforce TLS 1.2:**

     Under the `#else` directive, change the value of the `flags` variable, as follows.

     ```
     DWORD flags = WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2;
     ```
   + **To enforce TLS 1.3:**

     Under the `#if defined(WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_3)` directive, change the value of the `flags` variable, as follows.

     ```
     DWORD flags = WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_3;
     ```

1. If you performed the preceding code changes, build and install the Amazon SDK for C\$1\$1 according to the instructions at [https://github.com/aws/aws-sdk-cpp\$1building-the-sdk](https://github.com/aws/aws-sdk-cpp#building-the-sdk).

1. For the service client in your application, enable `verifySSL` in its client configuration, if this option isn’t already enabled.

### To enforce TLS 1.2 with WinINet and IXMLHTTPRequest2
<a name="to-enforce-tls-1-2-with-wininet-and-ixmlhttprequest2"></a>

There is no API to specify the secure protocol for the WinINet and IXMLHTTPRequest2 libraries. So the Amazon SDK for C\$1\$1 uses the default for the operating system. You can update the Windows registry to enforce the use of TLS 1.2, as shown in the following procedure. Be advised, however, that the result is a global change that impacts all applications that depend on Schannel.

1. Open Registry Editor and go to `Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols`.

1. If they don’t already exist, create the following subkeys: `TLS 1.0,`, `TLS 1.1`, and `TLS 1.2`.

1. Under each of the subkeys, create a `Client` subkey and a `Server` subkey.

1. Create the following keys and values.

   ```
    Key name                          Key type   Value
    --------                          ---------  -----
    TLS 1.0\Client\DisabledByDefault  DWORD      0
    TLS 1.1\Client\DisabledByDefault  DWORD      0
    TLS 1.2\Client\DisabledByDefault  DWORD      0
    TLS 1.0\Client\Enabled            DWORD      0
    TLS 1.1\Client\Enabled            DWORD      0
    TLS 1.2\Client\Enabled            DWORD      1
   ```

   Notice that `TLS 1.2\Client\Enabled` is the only key that’s set to 1. Setting this key to 1 enforces TLS 1.2 as the only acceptable secure protocol.

### To enforce TLS 1.3 with WinINet and IXMLHTTPRequest2
<a name="to-enforce-tls-1-3-with-wininet-and-ixmlhttprequest2"></a>

There is no API to specify the secure protocol for the WinINet and IXMLHTTPRequest2 libraries. So the Amazon SDK for C\$1\$1 uses the default for the operating system. You can update the Windows registry to enforce the use of TLS 1.3, as shown in the following procedure. Be advised, however, that the result is a global change that impacts all applications that depend on Schannel.

1. Open Registry Editor and go to `Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols`.

1. If they don’t already exist, create the following subkeys: `TLS 1.0,`, `TLS 1.1`, `TLS 1.2` and `TLS 1.3`.

1. Under each of the subkeys, create a `Client` subkey and a `Server` subkey.

1. Create the following keys and values.

   ```
    Key name                          Key type   Value
    --------                          ---------  -----
    TLS 1.0\Client\DisabledByDefault  DWORD      0
    TLS 1.1\Client\DisabledByDefault  DWORD      0
    TLS 1.2\Client\DisabledByDefault  DWORD      0
    TLS 1.3\Client\DisabledByDefault  DWORD      0
    TLS 1.0\Client\Enabled            DWORD      0
    TLS 1.1\Client\Enabled            DWORD      0
    TLS 1.2\Client\Enabled            DWORD      0
    TLS 1.3\Client\Enabled            DWORD      1
   ```

   Notice that `TLS 1.3\Client\Enabled` is the only key that’s set to 1. Setting this key to 1 enforces TLS 1.3 as the only acceptable secure protocol.

# Amazon S3 Encryption Client Migration (V1 to V2)
<a name="s3-encryption-migration-v1-v2"></a>

**Note**  
If you are using V2 of the Amazon S3 encryption client and want to migrate to V3, see [Amazon S3 Encryption Client Migration (V2 to V3)](s3-encryption-migration-v2-v3.md).

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
<a name="migration-overview-v1-v2"></a>

This migration happens in two phases:

1. **Update existing clients to read new formats.** First, deploy an updated version of the Amazon SDK for C\$1\$1 to your application. This allows existing V1 encryption clients to decrypt objects written by the new V2 clients. If your application uses multiple Amazon 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
<a name="update-existing-clients-to-read-new-formats-v1-v2"></a>

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 Amazon SDK for C\$1\$1
<a name="build-and-install-the-latest-version-of-the-sdk-cpp-v1-v2"></a>

 **Applications Consuming the SDK from Source** 

If you build and install the Amazon SDK for C\$1\$1 from source, download or clone the SDK source from [https://github.com/aws/aws-sdk-cpp](https://github.com/aws/aws-sdk-cpp) on GitHub . Then repeat your normal build and install steps.

If you are upgrading Amazon SDK for C\$1\$1 from a version earlier than 1.8.x, see this [CHANGELOG](https://github.com/aws/aws-sdk-cpp/blob/master/CHANGELOG.md) for breaking changes introduced in each major version. For more information about how to build and install the Amazon SDK for C\$1\$1, see [Getting the Amazon SDK for C\$1\$1 from source code](sdk-from-source.md).

 **Applications Consuming the SDK from Vcpkg** 

If your application uses [Vcpkg](https://github.com/microsoft/vcpkg) to track SDK updates, simply use your existing Vcpkg upgrade method to upgrade the SDK to the latest version. Keep in mind, there is a delay between when a version is released and when it is available through a package manager. The most recent version is always available through [installing from source](sdk-from-source.md). 

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 Amazon SDK for C\$1\$1, see [Getting the Amazon SDK for C\$1\$1 from a package manager](sdk-from-pm.md).

### Build, Install, and Deploy Your Applications
<a name="build-install-and-deploy-your-applications-v1-v2"></a>

If your application is statically linking against the Amazon SDK for C\$1\$1, 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
<a name="migrate-encryption-and-decryption-clients-to-v2-v1-v2"></a>

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 Amazon SDK for C\$1\$1.

### Using New Encryption Materials
<a name="using-new-encryption-materials-v1-v2"></a>

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` with `KMSWithContextEncryptionMaterials` 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 `SimpleEncryptionMaterials` when creating an S3 encryption client:**  
  + When creating a V2 Amazon S3 encryption client, replace `SimpleEncryptionMaterials` with `SimpleEncryptionMaterialsWithGCMAAD` 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.

 **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
<a name="additional-examples-v1-v2"></a>

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
<a name="decrypt-objects-encrypted-by-legacy-amazon-s3-encryption-clients-v1-v2"></a>

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 Amazon SDK for C\$1\$1 to encrypt the objects, you're likely using the deprecated methods if:
+ You used `SimpleEncryptionMaterials` or `KMSEncryptionMaterials`.
+ You used `ENCRYPTION_ONLY` as `Crypto 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
<a name="decrypt-objects-with-range-v1-v2"></a>

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
<a name="decrypt-objects-with-any-cmk-v1-v2"></a>

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](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3encryption) on Github.

# Amazon S3 Encryption Client Migration (V2 to V3)
<a name="s3-encryption-migration-v2-v3"></a>

**Note**  
If you are using V1 of the Amazon S3 encryption client, you must first migrate to V2 before migrating to V3. See [Amazon S3 Encryption Client Migration (V1 to V2)](s3-encryption-migration-v1-v2.md).

This topic shows how to migrate your applications from Version 2 (V2) to Version 3 (V3) of the Amazon Simple Storage Service (Amazon S3) encryption client and ensure application availability throughout the migration process. V3 introduces the `ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY` algorithm and Commitment Policies to enhance security by protecting against data key tampering in Instruction Files.

## Migration Overview
<a name="s3-encryption-migration-v2-v3-overview"></a>

This migration happens in two phases:

1. **Update existing clients to read new formats.** First, deploy an updated version of the Amazon SDK for C\$1\$1 to your application. This allows existing V2 encryption clients to decrypt objects written by the new V3 clients. If your application uses multiple Amazon SDKs, you must upgrade each SDK separately.

2. **Migrate encryption and decryption clients to V3.** Once all of your V2 encryption clients can read new formats, you can migrate your existing encryption and decryption clients to their respective V3 versions.

## Understanding V3 Concepts
<a name="s3-encryption-migration-v2-v3-concepts"></a>

Version 3 of the Amazon S3 encryption client introduces new security features that enhance protection against data key tampering. Understanding these concepts is essential for a successful migration.

### Commitment Policy
<a name="s3-encryption-migration-v2-v3-commitment-policy"></a>

Commitment Policies control how the encryption client handles key commitment during encryption and decryption operations. V3 provides three policy options to support different migration scenarios and security requirements:

**`FORBID_ENCRYPT_ALLOW_DECRYPT`**  
**Encryption behavior:** Encrypts objects without key commitment, using the same algorithms as V2.  
**Decryption behavior:** Allows decryption of objects encrypted with and without key commitment.  
**Security implications:** This policy does not enforce key commitment and may allow tampering with the encrypted data key in Instruction Files. Use this policy only during the initial migration phase when you need V2 clients to read newly encrypted objects.  
**Version compatibility:** Objects encrypted with this policy can be read by all V2 and V3 implementations.

**`REQUIRE_ENCRYPT_ALLOW_DECRYPT` (Default)**  
**Encryption behavior:** Encrypts objects with key commitment using the `ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY` algorithm.  
**Decryption behavior:** Allows decryption of both objects encrypted with key commitment and objects encrypted without key commitment.  
**Security implications:** This policy provides strong security for newly encrypted objects while maintaining backward compatibility for reading older objects. This is the recommended policy for most migration scenarios.  
**Version compatibility:** Objects encrypted with this policy can only be read by V3 and the latest V2 implementations. V2 clients cannot decrypt these objects. However, V3 clients using this policy can still decrypt objects encrypted by V2 clients.

**`REQUIRE_ENCRYPT_REQUIRE_DECRYPT`**  
**Encryption behavior:** Encrypts objects with key commitment using the `ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY` algorithm.  
**Decryption behavior:** Only allows decryption of objects encrypted with key commitment. Rejects objects encrypted without key commitment.  
**Security implications:** This policy provides the highest level of security by enforcing key commitment for all operations. Use this policy only after all objects have been re-encrypted with key commitment and you no longer need to read legacy V1 or V2 encrypted objects.  
**Version compatibility:** Objects encrypted with this policy can only be read by V3 and the latest V2 implementations. Additionally, clients using this policy cannot decrypt objects encrypted by V1 or V2 clients.

**Migration considerations:** During migration, start with `FORBID_ENCRYPT_ALLOW_DECRYPT` if you need V2 clients to read new objects, then move to `REQUIRE_ENCRYPT_ALLOW_DECRYPT` once all clients are upgraded to V3. Finally, consider `REQUIRE_ENCRYPT_REQUIRE_DECRYPT` only after all legacy objects have been re-encrypted.

### ALG\$1AES\$1256\$1GCM\$1HKDF\$1SHA512\$1COMMIT\$1KEY Algorithm
<a name="s3-encryption-migration-v2-v3-aes-gcm-kc"></a>

The `ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY` algorithm is a new encryption algorithm introduced in V3 that provides enhanced security for encrypted data keys stored in Instruction Files.

**Instruction File impact:** The `ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY` algorithm only impacts Instruction Files, which are separate S3 objects that store encryption metadata including the encrypted data key. Objects that store encryption metadata in object metadata (the default storage method) are not affected by this algorithm change.

**Protection against tampering:** The `ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY` algorithm protects against data key tampering by cryptographically binding the encrypted data key to the encryption context. This prevents attackers from substituting a different encrypted data key in the Instruction File, which could potentially lead to decryption with an unintended key.

**Version compatibility:** Objects encrypted with the `ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY` algorithm can only be decrypted by V3 implementations and the latest V2 transition versions of the SDK that include V3 decryption support.

**Warning**  
**Important:** Before enabling encryption with the `ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY` algorithm (by using `REQUIRE_ENCRYPT_ALLOW_DECRYPT` or `REQUIRE_ENCRYPT_REQUIRE_DECRYPT` commitment policies), you must ensure that all clients that will read these objects have been upgraded to V3 or the latest V2 transition version that supports V3 decryption. Failure to upgrade all readers first will result in decryption failures for newly encrypted objects.

## Update Existing Clients to Read New Formats
<a name="s3-encryption-migration-v2-v3-update-clients"></a>

You must first update your existing clients to the latest SDK release. After completing this step, your application's V2 clients will be able to decrypt objects encrypted by V3 encryption clients without updating your application's code base.

### Build and Install the Latest Version of the Amazon SDK for C\$1\$1
<a name="s3-encryption-migration-v2-v3-build-install-sdk"></a>

 **Applications Consuming the SDK from Source** 

If you build and install the Amazon SDK for C\$1\$1 from source, download or clone the SDK source from [https://github.com/aws/aws-sdk-cpp](https://github.com/aws/aws-sdk-cpp) on GitHub . Then repeat your normal build and install steps.

If you are upgrading Amazon SDK for C\$1\$1 from a version earlier than 1.11.x, see this [CHANGELOG](https://github.com/aws/aws-sdk-cpp/blob/main/CHANGELOG.md) for breaking changes introduced in each major version. For more information about how to build and install the Amazon SDK for C\$1\$1, see [Getting the Amazon SDK for C\$1\$1 from source code](sdk-from-source.md).

 **Applications Consuming the SDK from Vcpkg** 

If your application uses [Vcpkg](https://github.com/microsoft/vcpkg) to track SDK updates, simply use your existing Vcpkg upgrade method to upgrade the SDK to the latest version. Keep in mind, there is a delay between when a version is released and when it is available through a package manager. The most recent version is always available through [installing from source](sdk-from-source.md).

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.11.x to support decryption of V3-encrypted objects.

For more information on using Vcpkg with the Amazon SDK for C\$1\$1, see [Getting the Amazon SDK for C\$1\$1 from a package manager](sdk-from-pm.md).

### Build, Install, and Deploy Your Applications
<a name="s3-encryption-migration-v2-v3-build-deploy-apps"></a>

If your application is statically linking against the Amazon SDK for C\$1\$1, 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 V3 encryption and decryption clients.

## Migrate Encryption and Decryption Clients to V3
<a name="s3-encryption-migration-v2-v3-migrate"></a>

The following steps show you how to successfully migrate your code from V2 to V3 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 Amazon SDK for C\$1\$1.

### Using V3 Encryption Clients
<a name="s3-encryption-migration-v2-v3-using-v3-clients"></a>

V3 introduces the `S3EncryptionClientV3` class and `CryptoConfigurationV3` to replace the V2 equivalents. The key differences in V3 are:
+ V3 uses `KMSWithContextEncryptionMaterials` (same as V2) but requires explicit configuration in `CryptoConfigurationV3`.
+ All `PutObject` operations require an encryption context map (can be empty).
+ V3 introduces Commitment Policies to control encryption and decryption behavior.
+ By default, V3 encrypts with key commitment using the `ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY` algorithm.
+ The legacy algorithm decryption configuration API changes from `config.SetSecurityProfile(SecurityProfile::V2_AND_LEGACY);` to `config.AllowLegacy();`.

 **Example: Migrating from V2 to V3 with KMS Encryption** 

 *Pre-migration (V2)* 

```
// Create encryption materials
auto materials = Aws::MakeShared<KMSWithContextEncryptionMaterials>("s3EncryptionV2", CUSTOMER_MASTER_KEY_ID);

// Create V2 crypto configuration
CryptoConfigurationV2 cryptoConfig(materials);

// Create V2 encryption client
S3EncryptionClientV2 encryptionClient(cryptoConfig);

// Put object with encryption context
Aws::Map<Aws::String, Aws::String> encryptionContext;
encryptionContext.emplace("client", "aws-sdk-cpp");
encryptionContext.emplace("version", "1.11.0");

PutObjectRequest putObjectRequest;
putObjectRequest.SetBucket(BUCKET_NAME);
putObjectRequest.SetKey(OBJECT_KEY);
// Set object body...

auto putOutcome = encryptionClient.PutObject(putObjectRequest, encryptionContext);

// Get object with encryption context
GetObjectRequest getObjectRequest;
getObjectRequest.SetBucket(BUCKET_NAME);
getObjectRequest.SetKey(OBJECT_KEY);

auto getOutcome = encryptionClient.GetObject(getObjectRequest, encryptionContext);
```

 *During migration (V3 with backward compatibility)* 

```
// Create encryption materials
auto materials = Aws::MakeShared<KMSWithContextEncryptionMaterials>("s3EncryptionV3", CUSTOMER_MASTER_KEY_ID);

// Create V3 crypto configuration with materials
CryptoConfigurationV3 cryptoConfig(materials);

// Set commitment policy to maintain compatibility with V2 encrypted objects
// This allows V3 clients to decrypt objects encrypted by the V2 client
cryptoConfig.SetCommitmentPolicy(CommitmentPolicy::REQUIRE_ENCRYPT_ALLOW_DECRYPT);

// Create V3 encryption client
S3EncryptionClientV3 encryptionClient(cryptoConfig);

// Put object with encryption context
Aws::Map<Aws::String, Aws::String> encryptionContext;
encryptionContext.emplace("client", "aws-sdk-cpp");
encryptionContext.emplace("version", "1.11.0");

PutObjectRequest putObjectRequest;
putObjectRequest.SetBucket(BUCKET_NAME);
putObjectRequest.SetKey(OBJECT_KEY);
// Set object body...

auto putOutcome = encryptionClient.PutObject(putObjectRequest, encryptionContext);

// Get object with encryption context
GetObjectRequest getObjectRequest;
getObjectRequest.SetBucket(BUCKET_NAME);
getObjectRequest.SetKey(OBJECT_KEY);

auto getOutcome = encryptionClient.GetObject(getObjectRequest, encryptionContext);
```

 *Post-migration (V3 with key commitment)* 

```
// Create encryption materials
auto materials = Aws::MakeShared<KMSWithContextEncryptionMaterials>("s3EncryptionV3", CUSTOMER_MASTER_KEY_ID);

// Create V3 crypto configuration with materials
CryptoConfigurationV3 cryptoConfig(materials);

// Use the default commitment policy (REQUIRE_ENCRYPT_REQUIRE_DECRYPT)
// This encrypts with key commitment and does not decrypt V2 objects
// cryptoConfig.SetCommitmentPolicy(CommitmentPolicy::REQUIRE_ENCRYPT_ALLOW_DECRYPT);

// Create V3 encryption client
S3EncryptionClientV3 encryptionClient(cryptoConfig);

// Put object with encryption context
Aws::Map<Aws::String, Aws::String> encryptionContext;
encryptionContext.emplace("client", "aws-sdk-cpp");
encryptionContext.emplace("version", "1.11.0");

PutObjectRequest putObjectRequest;
putObjectRequest.SetBucket(BUCKET_NAME);
putObjectRequest.SetKey(OBJECT_KEY);
// Set object body...

auto putOutcome = encryptionClient.PutObject(putObjectRequest, encryptionContext);

// Get object with encryption context
GetObjectRequest getObjectRequest;
getObjectRequest.SetBucket(BUCKET_NAME);
getObjectRequest.SetKey(OBJECT_KEY);

auto getOutcome = encryptionClient.GetObject(getObjectRequest, encryptionContext);
```

## Additional Examples
<a name="s3-encryption-migration-v2-v3-examples"></a>

This section provides additional examples for configuring V3 encryption client options to support various migration scenarios and requirements.

### Enabling Legacy Support
<a name="s3-encryption-migration-v2-v3-examples-legacy-support"></a>

V3 clients can decrypt objects encrypted by V2 clients only when using the `REQUIRE_ENCRYPT_ALLOW_DECRYPT` or `FORBID_ENCRYPT_ALLOW_DECRYPT` commitment policies. However, if you need to decrypt objects encrypted by V1 clients, you must explicitly enable legacy support using the `AllowLegacy()` method.

**When to use legacy support:**
+ You have objects in S3 that were encrypted using V1 of the S3 Encryption Client.
+ You need to read these V1-encrypted objects with your V3 client during the migration process.
+ You are using the `REQUIRE_ENCRYPT_ALLOW_DECRYPT` or `FORBID_ENCRYPT_ALLOW_DECRYPT` commitment policy.

**Warning**  
Legacy support should only be enabled temporarily during migration. Once all V1 objects have been re-encrypted with V2 or V3, disable legacy support to ensure maximum security.

**Example: Enabling Legacy Support**

```
// Create encryption materials
auto materials = Aws::MakeShared<KMSWithContextEncryptionMaterials>("s3EncryptionV3", CUSTOMER_MASTER_KEY_ID);

// Create V3 crypto configuration
CryptoConfigurationV3 cryptoConfig(materials);

// Enable legacy support to read V1 encrypted objects
cryptoConfig.AllowLegacy();

// Set commitment policy (default is REQUIRE_ENCRYPT_REQUIRE_DECRYPT but we need to allow decryption)
cryptoConfig.SetCommitmentPolicy(CommitmentPolicy::REQUIRE_ENCRYPT_ALLOW_DECRYPT);

// Create V3 encryption client with legacy support enabled
S3EncryptionClientV3 encryptionClient(cryptoConfig);

// Now you can decrypt objects encrypted by V1, V2, and V3 clients
GetObjectRequest getObjectRequest;
getObjectRequest.SetBucket(BUCKET_NAME);
getObjectRequest.SetKey(LEGACY_OBJECT_KEY);

Aws::Map<Aws::String, Aws::String> encryptionContext;
auto getOutcome = encryptionClient.GetObject(getObjectRequest, encryptionContext);
```

### Configuring Storage Method
<a name="s3-encryption-migration-v2-v3-examples-storage-method"></a>

The S3 Encryption Client can store encryption metadata in two ways: as object metadata (the default) or in a separate Instruction File. You can configure the storage method using the `SetStorageMethod()` method on `CryptoConfigurationV3`.

**Storage method options:**

**`METADATA` (Default)**  
Encryption metadata is stored in the object's metadata headers. This is the most common and convenient method as all encryption information is stored with the object itself.  
**When to use:** Use this method for most scenarios. It simplifies object management since encryption metadata travels with the object.

**`INSTRUCTION_FILE`**  
Encryption metadata is stored in a separate S3 object (the Instruction File) with the suffix `.instruction`.  
**When to use:** Use this method when object metadata size is a concern or when you need to separate encryption metadata from the encrypted object. Note that using Instruction Files requires managing two S3 objects (the encrypted object and its instruction file) instead of one.

**Example: Configuring Storage Method**

```
// Create encryption materials
auto materials = Aws::MakeShared<KMSWithContextEncryptionMaterials>("s3EncryptionV3", CUSTOMER_MASTER_KEY_ID);

// Create V3 crypto configuration
CryptoConfigurationV3 cryptoConfig(materials);

// Option 1: Use metadata storage (default, can be omitted)
cryptoConfig.SetStorageMethod(StorageMethod::METADATA);

// Option 2: Use instruction file storage
cryptoConfig.SetStorageMethod(StorageMethod::INSTRUCTION_FILE);

// Create V3 encryption client with the configured storage method
S3EncryptionClientV3 encryptionClient(cryptoConfig);

// Put object - encryption metadata will be stored according to the configured method
Aws::Map<Aws::String, Aws::String> encryptionContext;
encryptionContext.emplace("client", "aws-sdk-cpp");

PutObjectRequest putObjectRequest;
putObjectRequest.SetBucket(BUCKET_NAME);
putObjectRequest.SetKey(OBJECT_KEY);
// Set object body...

auto putOutcome = encryptionClient.PutObject(putObjectRequest, encryptionContext);

// If using INSTRUCTION_FILE, a separate object with key "OBJECT_KEY.instruction" will be created
```

**Note**  
When using the `INSTRUCTION_FILE` storage method, remember that deleting the encrypted object does not automatically delete the instruction file. You must manage both objects separately.