

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 中的 Amazon S3 加密客户端迁移（V1 到 V2） 适用于 PHP 的 AWS SDK 版本 3
<a name="s3-encryption-migration-v1-v2"></a>

**注意**  
如果您使用的是 Amazon S3 加密客户端的版本 2 (V2) 并想要迁移到版本 3 (V3)，请参阅[中的 Amazon S3 加密客户端迁移（V2 到 V3） 适用于 PHP 的 AWS SDK 版本 3](s3-encryption-migration-v2-v3.md)。

此主题介绍了如何将应用程序从 Amazon Simple Storage Service (Amazon S3) 加密客户端的版本 1 (V1) 迁移到版本 2 (V2)，并确保应用程序在整个迁移过程中的可用性。

## 迁移概述
<a name="migration-overview-v1-v2"></a>

此迁移分为两个阶段：

1. **更新现有客户端以读取新格式。**首先，将 适用于 PHP 的 AWS SDK 的已更新版本部署到应用程序中。这允许现有 V1 加密客户端解密由新的 V2 客户端写入的对象。如果您的应用程序使用多个 AWS SDK，则必须单独升级每个 SDK。

2. **将加密和解密客户端迁移到 V2。**一旦所有 V1 加密客户端都能读取新格式，就可以将现有加密和解密客户端迁移到各自的 V2 版本。

## 更新现有客户端以读取新格式
<a name="update-existing-clients-to-read-new-formats-v1-v2"></a>

V2 加密客户端使用旧版本客户端不支持的加密算法。迁移的第一步是将 V1 解密客户端更新到最新 SDK 版本。完成此步骤后，您的应用程序的 V1 客户端将能够解密由 V2 加密客户端加密的对象。有关 适用于 PHP 的 AWS SDK的每个主要版本，请参阅下文的详细信息。

### Upgrading 适用于 PHP 的 AWS SDK 版本 3
<a name="upgrading-aws-sdk-for-php-version-3-v1-v2"></a>

版本 3 是 适用于 PHP 的 AWS SDK的最新版本。必须使用版本 3.148.0 或更高版本的 `aws/aws-sdk-php` 包才能完成此迁移。

 **从命令行安装** 

对于使用 Composer 来安装的项目，在 Composer 文件中，将 SDK 包更新到 SDK 的 3.148.0 版本，然后运行以下命令。

```
composer update aws/aws-sdk-php
```

 **使用 Phar 或 Zip 文件进行安装** 

使用以下方法之一。请务必将已更新的 SDK 文件放在代码所需位置，该位置由 require 语句确定。

对于使用 Phar 文件来安装的项目，请下载已更新的文件：[`aws.phar`](https://docs.aws.amazon.com/aws-sdk-php/v3/download/aws.phar)。

```
<?php
  require '/path/to/aws.phar';
?>
```

对于使用 Zip 文件来安装的项目，请下载已更新的文件：[``](https://docs.aws.amazon.com/aws-sdk-php/v3/download/aws.zip)。

```
<?php
  require '/path/to/aws-autoloader.php';
?>
```

## 将加密和解密客户端迁移到 V2
<a name="migrate-encryption-and-decryption-clients-to-v2-v1-v2"></a>

更新客户端以读取新的加密格式后，您可以将应用程序更新到 V2 加密和解密客户端。以下步骤展示了如何成功地将代码从 V1 迁移到 V2。

### 更新到 V2 客户端的要求
<a name="requirements-for-updating-to-v2-clients-v1-v2"></a>

1. AWS KMS 加密上下文必须传递到`S3EncryptionClientV2::putObject`和`S3EncryptionClientV2::putObjectAsync`方法中。 AWS KMS 加密上下文是密钥值对的关联数组，必须将其添加到加密上下文中才能进行密钥加密。 AWS KMS 如果不需要其他上下文，则可以传递空数组。

2.必须将 `@SecurityProfile` 传递到 `S3EncryptionClientV2` 中的 `getObject` 和 `getObjectAsync` 方法中。`@SecurityProfile` 是这些 `getObject...` 方法的新必填参数。如果设置为`'V2'`，则只能解密 V2-compatible 格式加密的对象。将此参数设置为`'V2_AND_LEGACY'`还允许对以 V1-compatible格式加密的对象进行解密。要支持迁移，请将 `@SecurityProfile` 设置为 `'V2_AND_LEGACY'`。`'V2'` 仅用于新应用程序开发。

3.（可选）将 `@KmsAllowDecryptWithAnyCmk` 参数包含在 `S3EncryptionClientV2::getObject` 和 `S3EncryptionClientV2::getObjectAsync* methods.` 中。添加了一个名为 `@KmsAllowDecryptWithAnyCmk` 的新参数。将此参数设置为 `true`，可在不提供 KMS 密钥的情况下进行解密。默认值为 `false`。

4. 要使用 V2 客户端进行解密，如果未将 `@KmsAllowDecryptWithAnyCmk` 参数设置为 `true`，则对于 `"getObject..."` 方法调用，必须为 `KmsMaterialsProviderV2` 构造函数提供 `kms-key-id`。

## 迁移示例
<a name="migration-examples-v1-v2"></a>

### 示例 1：迁移到 V2 客户端
<a name="example-1-migrating-to-v2-clients-v1-v2"></a>

 **Pre-migration** 

```
use Aws\S3\Crypto\S3EncryptionClient;
use Aws\S3\S3Client;

$encryptionClient = new S3EncryptionClient(
    new S3Client([
        'profile' => 'default',
        'region' => 'us-east-1',
        'version' => 'latest',
    ])
);
```

 **Post-migration** 

```
use Aws\S3\Crypto\S3EncryptionClientV2;
use Aws\S3\S3Client;

$encryptionClient = new S3EncryptionClientV2(
    new S3Client([
        'profile' => 'default',
        'region' => 'us-east-1',
        'version' => 'latest',
    ])
);
```

### 示例 2：使用 AWS KMS 使用 kms-key-id
<a name="example-2-using-kms-with-kms-key-id-v1-v2"></a>

**注意**  
这些示例使用在示例 1 中定义的导入和变量。例如 `$encryptionClient`。

 **Pre-migration** 

```
use Aws\Crypto\KmsMaterialsProvider;
use Aws\Kms\KmsClient;

$kmsKeyId = 'kms-key-id';
$materialsProvider = new KmsMaterialsProvider(
    new KmsClient([
        'profile' => 'default',
        'region' => 'us-east-1',
        'version' => 'latest',
    ]),
    $kmsKeyId
);

$bucket = 'the-bucket-name';
$key = 'the-file-name';
$cipherOptions = [
    'Cipher' => 'gcm',
    'KeySize' => 256,
];

$encryptionClient->putObject([
    '@MaterialsProvider' => $materialsProvider,
    '@CipherOptions' => $cipherOptions,
    'Bucket' => $bucket,
    'Key' => $key,
    'Body' => fopen('file-to-encrypt.txt', 'r'),
]);

$result = $encryptionClient->getObject([
    '@MaterialsProvider' => $materialsProvider,
    '@CipherOptions' => $cipherOptions,
    'Bucket' => $bucket,
    'Key' => $key,
]);
```

 **Post-migration** 

```
use Aws\Crypto\KmsMaterialsProviderV2;
use Aws\Kms\KmsClient;

$kmsKeyId = 'kms-key-id';
$materialsProvider = new KmsMaterialsProviderV2(
    new KmsClient([
        'profile' => 'default',
        'region' => 'us-east-1',
        'version' => 'latest',
    ]),
    $kmsKeyId
);

$bucket = 'the-bucket-name';
$key = 'the-file-name';
$cipherOptions = [
    'Cipher' => 'gcm',
    'KeySize' => 256,
];

$encryptionClient->putObject([
    '@MaterialsProvider' => $materialsProvider,
    '@CipherOptions' => $cipherOptions,
    '@KmsEncryptionContext' => ['context-key' => 'context-value'],
    'Bucket' => $bucket,
    'Key' => $key,
    'Body' => fopen('file-to-encrypt.txt', 'r'),
]);
$result = $encryptionClient->getObject([
    '@KmsAllowDecryptWithAnyCmk' => true,
    '@SecurityProfile' => 'V2_AND_LEGACY',
    '@MaterialsProvider' => $materialsProvider,
    '@CipherOptions' => $cipherOptions,
    'Bucket' => $bucket,
    'Key' => $key,
]);
```