

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# AWS SDK for PHP 버전 3의 Amazon S3 암호화 클라이언트 마이그레이션(V2에서 V3로)
<a name="s3-encryption-migration-v2-v3"></a>

**참고**  
Amazon S3 암호화 클라이언트 버전 1(V1)을 사용하는 경우 버전 3(V3)으로 마이그레이션하기 전에 먼저 버전 2(V2)로 마이그레이션해야 합니다. [AWS SDK for PHP 버전 3의 Amazon S3 암호화 클라이언트 마이그레이션(V1에서 V2로)](s3-encryption-migration-v1-v2.md)을(를) 참조하세요.

이 주제에서는 Amazon Simple Storage Service(Amazon S3) 암호화 클라이언트 버전 2(V2)에서 버전 3(V3)으로 애플리케이션을 마이그레이션하고 마이그레이션 프로세스 전반에 걸쳐 애플리케이션 가용성을 보장하는 방법을 보여줍니다. 버전 3에는 보안을 강화하고 데이터 키 변조로부터 보호하기 위해 키 커밋 및 커밋 정책이 포함된 AES GCM이 도입되었습니다.

## 마이그레이션 개요
<a name="s3-encryption-migration-v2-v3-overview"></a>

이 마이그레이션은 다음 두 단계로 진행됩니다.

1. **새 형식을 읽도록 기존 클라이언트를 업데이트하세요.** 먼저, AWS SDK for PHP 의 업데이트된 버전을 애플리케이션에 배포합니다. 이렇게 하면 기존 V2 암호화 클라이언트가 새 V3 클라이언트가 작성한 객체를 해독할 수 있습니다. 애플리케이션에서 다중 AWS SDKs 사용하는 경우 각 SDK를 별도로 업그레이드해야 합니다.

2. **암호화 및 복호화 클라이언트를 V3로 마이그레이션합니다.** 모든 V2 암호화 클라이언트가 새 형식을 읽을 수 있게 되면 기존 암호화 및 복호화 클라이언트를 해당 V3 버전으로 마이그레이션할 수 있습니다.

## V3 개념 이해
<a name="s3-encryption-migration-v2-v3-concepts"></a>

Amazon S3 암호화 클라이언트 버전 3에는 커밋 정책과 키 커밋 알고리즘이 포함된 AES GCM이라는 두 가지 주요 보안 개선 사항이 도입되었습니다. 이러한 개념을 이해하는 것은 성공적인 마이그레이션에 필수적입니다.

### 약정 정책
<a name="s3-encryption-migration-v2-v3-concepts-commitment-policy"></a>

커밋 정책은 암호화 및 복호화 작업 중에 암호화 클라이언트가 키 커밋을 처리하는 방법을 제어합니다. 버전 3은 세 가지 정책 옵션을 제공합니다.

`FORBID_ENCRYPT_ALLOW_DECRYPT`  
**암호화 동작:** 키 커밋 없이 객체를 암호화합니다.  
**복호화 동작:** 키 커밋을 사용하거나 사용하지 않고 암호화된 객체의 복호화를 허용합니다.  
**보안 영향:**이 정책은 새로 암호화된 객체에 키 커밋을 적용하지 않으므로 데이터 키 변조가 허용될 수 있습니다. V2 클라이언트와의 호환성을 유지해야 하는 초기 마이그레이션 단계에서만이 정책을 사용합니다.  
**버전 호환성:**이 정책으로 암호화된 객체는 모든 V2 및 V3 구현에서 읽을 수 있습니다.

`REQUIRE_ENCRYPT_ALLOW_DECRYPT`  
**암호화 동작:** `ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY` 알고리즘을 사용하여 키 커밋으로 객체를 암호화합니다.  
**복호화 동작:** 키 커밋을 사용하거나 사용하지 않고 암호화된 객체의 복호화를 허용합니다.  
**보안 영향:**이 정책은 기존 객체를 읽을 수 있는 기능을 유지하면서 새로 암호화된 객체에 대한 보안을 강화합니다. 이는 대부분의 마이그레이션 시나리오에 권장되는 정책입니다.  
**버전 호환성:**이 정책으로 암호화된 객체는 V3 및 최신 V2 구현에서만 읽을 수 있습니다.  
**마이그레이션 고려 사항:**이 정책을 사용하기 전에 암호화된 객체를 읽어야 하는 모든 클라이언트가 V3 또는 최신 V2로 업그레이드되었는지 확인합니다.

`REQUIRE_ENCRYPT_REQUIRE_DECRYPT`  
**암호화 동작:** `ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY` 알고리즘을 사용하여 키 커밋으로 객체를 암호화합니다.  
**복호화 동작:** 키 커밋으로 암호화된 객체의 복호화만 허용합니다. 키 커밋 없이 암호화된 객체는 복호화에 실패합니다.  
**보안 영향:**이 정책은 암호화 및 복호화 모두에 대한 키 커밋을 적용하여 최고 수준의 보안을 제공합니다. 키 커밋을 사용하도록 모든 객체를 마이그레이션한 후에만이 정책을 사용합니다.  
**버전 호환성:** V3 구현만이 정책을 사용할 수 있습니다. 이 정책을 사용하여 V1 또는 V2 암호화된 객체를 복호화하려고 하면 실패합니다.  
**마이그레이션 고려 사항:**이 정책은 전체 마이그레이션을 완료하고 키 커밋으로 기존 객체를 모두 다시 암호화한 후에만 사용해야 합니다.

### 키 커밋이 있는 AES GCM
<a name="s3-encryption-migration-v2-v3-concepts-aes-gcm-kc"></a>

키 커밋(`ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY`)이 포함된 AES GCM 알고리즘은 V3에 도입된 새로운 암호화 알고리즘으로, 데이터 키 변조 공격으로부터 보호합니다.

**보안 강화:** 데이터 키를 암호화된 콘텐츠에 암호화 방식으로 바인딩하여 데이터 키 변조를 `ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY` 방지합니다. 이렇게 하면 공격자가 복호화 중에 다른 데이터 키를 대체하지 못하여 의도하지 않은 데이터가 복호화될 수 있습니다.

**버전 호환성: **로 암호화된 객체는 V3 및 Amazon S3 암호화 클라이언트의 최신 V2 구현에서만 해독할 `ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY` 수 있습니다. V1 클라이언트는이 알고리즘으로 암호화된 객체를 해독할 수 없습니다.

**중요**  
**업그레이드 요구 사항:** `ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY` (REQUIRE\_ENCRYPT\_ALLOW\_DECRYPT 또는 REQUIRE\_ENCRYPT\_REQUIRE\_DECRYPT 정책을 사용하여)를 사용하여 암호화를 활성화하기 전에 암호화된 객체를 읽어야 하는 모든 클라이언트가 V3로 업그레이드되었는지 확인해야 합니다. 모든 리더를 업그레이드하지 않으면 키 커밋으로 암호화된 객체에 대한 복호화 실패가 발생합니다.

## 새 형식을 읽도록 기존 클라이언트를 업데이트하세요
<a name="s3-encryption-migration-v2-v3-update-clients"></a>

V3 암호화 클라이언트는 이전 버전의 클라이언트가 지원하지 않는 암호화 알고리즘과 키 커밋 기능을 사용합니다. 마이그레이션의 첫 번째 단계는 V2 복호화 클라이언트를 최신 SDK 릴리스로 업데이트하는 것입니다. 이 단계를 완료하면 애플리케이션의 V2 클라이언트가 V3 암호화 클라이언트로 암호화된 객체를 해독할 수 있습니다. 의 각 설치 방법에 대한 자세한 내용은 아래를 참조하세요 AWS SDK for PHP.

### 최신 SDK 버전 빌드 및 설치
<a name="s3-encryption-migration-v2-v3-update-clients-sdk"></a>

이 마이그레이션을 완료하려면 V3 암호화 클라이언트 지원이 포함된 `aws/aws-sdk-php` 패키지의 최신 버전을 사용해야 합니다.

 **Composer에서 설치** 

Composer를 사용하여 설치된 프로젝트의 경우 Composer 파일에서 SDK 패키지를 최신 버전의 SDK로 업데이트한 다음 다음 명령을 실행합니다.

```
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';
?>
```

### 애플리케이션 구축, 설치 및 배포
<a name="s3-encryption-migration-v2-v3-update-clients-deploy"></a>

SDK를 업데이트한 후 애플리케이션을 다시 빌드하고 배포하여 모든 구성 요소가 업데이트된 버전을 사용하고 있는지 확인합니다. 이 단계는 V2 클라이언트가 V3 클라이언트로 암호화된 객체를 읽을 수 있도록 하는 데 매우 중요합니다.

조직의 표준 배포 절차에 따라 업데이트된 애플리케이션을 롤아웃합니다. 암호화 및 복호화 클라이언트를 V3로 마이그레이션하기 전에 애플리케이션의 모든 인스턴스가 업데이트되었는지 확인합니다.

배포 후 애플리케이션이 여전히 기존 객체를 해독할 수 있고 정상 작업 중에 오류가 발생하지 않는지 확인합니다. 이렇게 하면 SDK 업데이트가 성공했으며 애플리케이션이 다음 마이그레이션 단계를 수행할 준비가 된 것입니다.

## 암호화 및 복호화 클라이언트를 V3로 마이그레이션
<a name="s3-encryption-migration-v2-v3-migrate"></a>

새 암호화 형식을 읽도록 클라이언트를 업데이트한 후 애플리케이션을 V3 암호화 및 복호화 클라이언트로 업데이트할 수 있습니다. 다음 예제에서는 V2에서 V3로 코드를 성공적으로 마이그레이션하는 방법을 보여줍니다.

### V3 암호화 클라이언트 사용
<a name="s3-encryption-migration-v2-v3-using-v3-clients"></a>

V3는 `S3EncryptionClientV3` 클래스 및를 도입`KmsMaterialsProviderV3`하여 V2에 상응하는 클래스를 대체합니다. V3의 주요 차이점은 다음과 같습니다.
+ V3는 `KmsMaterialsProviderV3` (V2와 동일)를 사용하지만 `GetObject` 호출에서 객체를 해독할 때 암호화 컨텍스트를 확인합니다.
+ V3는 암호화 및 복호화 동작을 제어하는 커밋 정책을 도입합니다.

 **예: KMS 암호화를 사용하여 V2에서 V3로 마이그레이션** 

 *마이그레이션 전(V2)* 

```
use Aws\S3\Crypto\S3EncryptionClientV2;
use Aws\S3\S3Client;
use Aws\Crypto\KmsMaterialsProviderV2;
use Aws\Kms\KmsClient;

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

$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',
   '@CommitmentPolicy' => 'FORBID_ENCRYPT_ALLOW_DECRYPT',
   '@MaterialsProvider' => $materialsProvider,
   '@CipherOptions' => $cipherOptions,
   'Bucket' => $bucket,
   'Key' => $key,
]);
```

 *마이그레이션 중(이전 버전과의 호환성을 갖춘 V3)* 

```
use Aws\S3\Crypto\S3EncryptionClientV3;
use Aws\S3\S3Client;
use Aws\Crypto\KmsMaterialsProviderV3;
use Aws\Kms\KmsClient;

// Create V3 encryption client
$encryptionClient = new S3EncryptionClientV3(
   new S3Client([
      'profile' => 'default',
      'region' => 'us-east-1',
      'version' => 'latest',
   ])
);

// Create encryption materials
$kmsKeyId = 'kms-key-id';
$materialsProvider = new KmsMaterialsProviderV3(
   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,
   '@CommitmentPolicy' => 'REQUIRE_ENCRYPT_ALLOW_DECRYPT',
   '@KmsEncryptionContext' => ['context-key' => 'context-value'],
   'Bucket' => $bucket,
   'Key' => $key,
   'Body' => fopen('file-to-encrypt.txt', 'r'),
]);

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

 *마이그레이션 후(키 커밋이 포함된 V3)* 

```
use Aws\S3\Crypto\S3EncryptionClientV3;
use Aws\S3\S3Client;
use Aws\Crypto\KmsMaterialsProviderV3;
use Aws\Kms\KmsClient;
 
// Create V3 encryption client
$encryptionClient = new S3EncryptionClientV3(
   new S3Client([
      'profile' => 'default',
      'region' => 'us-east-1',
      'version' => 'latest',
   ])
);

// Create encryption materials
$kmsKeyId = 'kms-key-id';
$materialsProvider = new KmsMaterialsProviderV3(
   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,
   // Use the commitment policy (REQUIRE_ENCRYPT_REQUIRE_DECRYPT)
   // This encrypts with key commitment and does not decrypt V2 objects
   '@CommitmentPolicy' => 'REQUIRE_ENCRYPT_REQUIRE_DECRYPT',
   '@KmsEncryptionContext' => ['context-key' => 'context-value'],
   'Bucket' => $bucket,
   'Key' => $key,
   'Body' => fopen('file-to-encrypt.txt', 'r'),
]);

$result = $encryptionClient->getObject([
   '@SecurityProfile' => 'V3',
   // Use the commitment policy (REQUIRE_ENCRYPT_REQUIRE_DECRYPT)
   // This encrypts with key commitment and does not decrypt V2 objects
   '@CommitmentPolicy' => 'REQUIRE_ENCRYPT_REQUIRE_DECRYPT',
   '@MaterialsProvider' => $materialsProvider,
   '@CipherOptions' => $cipherOptions,
   'Bucket' => $bucket,
   'Key' => $key,
]);
```

V3의 주요 차이점:
+ `KmsMaterialsProviderV2` 대신 `KmsMaterialsProviderV3` 사용
+ `@KmsEncryptionContext` 파라미터는 `putObject` 여전히 작업에 필요합니다.
+ `@KmsEncryptionContext` 파라미터는 `getObject` 작업에 대해 선택 사항이며 제공된 암호화 컨텍스트가 객체의 컨텍스트와 일치하는지 확인합니다.
+ `@SecurityProfile` 파라미터는 해독할 수 있는 암호화 버전을 제어합니다. 마이그레이션 중에 V1 및 V2 암호화된 객체 읽기`'V3_AND_LEGACY'`를 지원하려면 로 설정
+ `@CommitmentPolicy` 파라미터는이 작업에 대한 커밋 정책을 제어합니다. 마이그레이션 중에 커밋되지 않은 암호화된 객체 읽기`'FORBID_ENCRYPT_ALLOW_DECRYPT'`를 지원하려면 로 설정

## 추가 예제
<a name="s3-encryption-migration-v2-v3-examples"></a>

다음 예제에서는 마이그레이션 프로세스를 관리하고 암호화 동작을 제어하는 데 도움이 되는 V3에서 사용할 수 있는 추가 구성 옵션을 보여줍니다.

### 레거시 지원 사용
<a name="s3-encryption-migration-v2-v3-examples-legacy"></a>

마이그레이션 중에 Amazon S3 암호화 클라이언트의 V1 또는 V2로 암호화된 객체를 복호화해야 할 수 있습니다. `@SecurityProfile` 파라미터는 V3 클라이언트가 해독할 수 있는 암호화 버전을 제어합니다.

**이 구성을 사용해야 하는 경우:** 애플리케이션이 V1 또는 V2 클라이언트로 암호화된 객체를 읽어야 하는 경우 `'V3_AND_LEGACY'` 보안 프로필을 사용합니다. 이는 버킷에 이전 암호화된 객체와 새 암호화된 객체가 혼합되어 있는 마이그레이션 기간 동안 흔히 발생합니다.

```
use Aws\S3\Crypto\S3EncryptionClientV3;
use Aws\S3\S3Client;
use Aws\Crypto\KmsMaterialsProviderV3;
use Aws\Kms\KmsClient;

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

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

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

// Decrypt objects encrypted with V1, V2, or V3
$result = $encryptionClient->getObject([
    '@SecurityProfile' => 'V3_AND_LEGACY',
    '@CommitmentPolicy' => 'REQUIRE_ENCRYPT_ALLOW_DECRYPT',
    '@MaterialsProvider' => $materialsProvider,
    '@CipherOptions' => $cipherOptions,
    'Bucket' => $bucket,
    'Key' => $key,
]);
```

`@SecurityProfile` 파라미터는 다음 값 중 하나를 받습니다.
+ `'V3'` (기본값): 키 커밋을 사용하여 V3로 암호화된 객체만 복호화
+ `'V3_AND_LEGACY'`: V1, V2 또는 V3로 암호화된 객체 복호화

**중요**  
마이그레이션을 완료하고 V3를 사용하여 모든 객체를 다시 암호화한 후에는 `@SecurityProfile` 파라미터를 제거하거나 로 설정`'V3'`하여 보안을 극대화해야 합니다.

### 스토리지 방법 구성
<a name="s3-encryption-migration-v2-v3-examples-storage"></a>

Amazon S3 암호화 클라이언트는 객체의 메타데이터 헤더 또는 별도의 명령 파일이라는 두 가지 방법으로 암호화 메타데이터를 저장할 수 있습니다. `@MetadataStrategy` 파라미터는 사용되는 스토리지 방법을 제어합니다.

**이 구성을 사용하는 경우:** 원본 객체 메타데이터를 보존`'INSTRUCTION_FILE'`해야 하거나 메타데이터 크기 제약이 있는 객체로 작업할 때 사용합니다. 객체와 함께 암호화 메타데이터를 저장할 수 있는 더 간단한 배포에는 `'METADATA'` (기본값)를 사용합니다.

```
use Aws\S3\Crypto\S3EncryptionClientV3;
use Aws\S3\S3Client;
use Aws\Crypto\KmsMaterialsProviderV3;
use Aws\Kms\KmsClient;

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

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

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

// Store encryption metadata in a separate instruction file
$encryptionClient->putObject([
    '@MaterialsProvider' => $materialsProvider,
    '@CipherOptions' => $cipherOptions,
    '@CommitmentPolicy' => 'REQUIRE_ENCRYPT_REQUIRE_DECRYPT',
    '@MetadataStrategy' => 'INSTRUCTION_FILE',
    '@KmsEncryptionContext' => ['context-key' => 'context-value'],
    'Bucket' => $bucket,
    'Key' => $key,
    'Body' => fopen('file-to-encrypt.txt', 'r'),
]);

// Store encryption metadata in object headers (default)
$encryptionClient->putObject([
    '@MaterialsProvider' => $materialsProvider,
    '@CipherOptions' => $cipherOptions,
    '@CommitmentPolicy' => 'REQUIRE_ENCRYPT_REQUIRE_DECRYPT',
    '@MetadataStrategy' => 'METADATA',
    '@KmsEncryptionContext' => ['context-key' => 'context-value'],
    'Bucket' => $bucket,
    'Key' => $key,
    'Body' => fopen('file-to-encrypt.txt', 'r'),
]);
```

`@MetadataStrategy` 파라미터는 다음 값 중 하나를 받습니다.
+ `'METADATA'` (기본값): 객체의 메타데이터 헤더에 암호화 메타데이터 저장
+ `'INSTRUCTION_FILE'`: 암호화 메타데이터를 접미사가 있는 별도의 명령 파일에 저장 `.instruction`

**참고**  
`'INSTRUCTION_FILE'`를 사용할 때 키 커밋 알고리즘이 포함된 AES GCM은 데이터 키 변조에 대한 추가 보호를 제공합니다. `'METADATA'` 스토리지를 사용하는 객체는이 추가 보호의 이점을 얻지 못합니다.