

# Amazon S3 관리형 키를 사용한 서버 측 암호화(SSE-S3) 사용
<a name="UsingServerSideEncryption"></a>

**중요**  
이제 Amazon S3가 Amazon S3 관리형 키를 사용한 서버 측 암호화(SSE-S3)를 Amazon S3 내 모든 버킷 암호화의 기본 수준으로 적용합니다. 2023년 1월 5일부터 Amazon S3로의 모든 새 객체 업로드는 추가 비용 없이 성능에 영향을 미치지 않고 자동으로 암호화됩니다. S3 버킷 기본 암호화 구성에 및 신규 객체 업로드에 대한 자동 암호화 상태는 CloudTrail 로그, S3 인벤토리, S3 Storage Lens, Amazon S3 콘솔에서 사용할 수 있으며, AWS CLI 및 AWS SDK에서 추가 Amazon S3 API 응답 헤더로도 사용할 수 있습니다. 자세한 내용은 [기본 암호화 관련 FAQ](https://docs.aws.amazon.com/AmazonS3/latest/userguide/default-encryption-faq.html)를 참조하십시오.

Amazon S3 버킷에 대한 모든 신규 객체 업로드는 기본적으로 Amazon S3 관리형 키(SSE-S3)를 통한 서버 측 암호화로 암호화됩니다.

서버 측 암호화를 사용하여 저장된 데이터를 보호합니다. Amazon S3는 각 객체를 고유한 키로 암호화합니다. 또한 추가 보안 조치로 주기적으로 바뀌는 키를 사용하여 키 자체를 암호화합니다. Amazon S3 서버 측 암호화는 256비트 고급 암호화 표준 갈루아/카운터 모드(AES-GCM)를 사용하여 업로드된 모든 객체를 암호화합니다.

Amazon S3 관리형 키(SSE-S3)를 통한 서버 측 암호화를 사용하는 경우 추가 요금이 부과되지 않습니다. 그러나 기본 암호화 기능을 구성하도록 요청할 경우 표준 Amazon S3 요청 요금이 발생합니다. 요금에 대한 자세한 내용은 [Amazon S3 요금](https://aws.amazon.com/s3/pricing/)을 참조하십시오.

Amazon S3 관리형 키만 사용하여 데이터 업로드를 암호화하도록 요구하는 경우 다음 버킷 정책을 사용할 수 있습니다. 예를 들어 다음 버킷 정책은 요청에 서버 측 암호화를 요청하는 `x-amz-server-side-encryption` 헤더가 포함되지 않을 경우 객체 업로드 권한을 거부합니다.

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Id": "PutObjectPolicy",
  "Statement": [
    {
      "Sid": "DenyObjectsThatAreNotSSES3",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::amzn-s3-demo-bucket/*",
      "Condition": {
        "StringNotEquals": {
          "s3:x-amz-server-side-encryption": "AES256"
        }
      }
    }
   ]
}
```

------

**참고**  
서버 측 암호화는 객체 메타데이터가 아닌 객체 데이터만 암호화합니다.

## 서버 측 암호화를 위한 API 지원
<a name="APISupportforServer-SideEncryption"></a>

모든 Amazon S3 버킷에는 기본적으로 암호화가 구성되어 있으며 S3 버킷에 업로드되는 신규 객체는 모두 저장 시 자동으로 암호화됩니다. Amazon S3 관리형 키(SSE-S3)를 사용한 서버 측 암호화가 Amazon S3 내 모든 버킷의 기본 암호화 구성입니다. 다른 유형의 암호화를 사용하려면 S3 `PUT` 요청에 사용할 서버 측 암호화 유형을 지정하거나 대상 버킷에 기본 암호화 구성을 업데이트할 수 있습니다.

`PUT` 요청에 다른 암호화 유형을 지정하려는 경우 AWS Key Management Service(AWS KMS) 키를 사용한 서버 측 암호화(SSE-KMS), AWS KMS 키를 사용한 이중 계층 서버 측 암호화(DSSE-KMS) 또는 고객 제공 키를 사용한 서버 측 암호화 (SSE-C)를 사용할 수 있습니다. 대상 버킷에 다른 기본 암호화 구성을 설정하려는 경우 SSE-KMS 또는 DSSE-KMS를 사용할 수 있습니다.

범용 버킷의 기본 암호화 구성을 변경하는 방법에 대한 자세한 내용은 [기본 암호화 구성](default-bucket-encryption.md) 섹션을 참조하세요.

버킷의 기본 암호화 구성을 SSE-KMS로 변경해도 버킷에 있는 기존 Amazon S3 객체의 암호화 유형은 변경되지 않습니다. 기본 암호화 구성을 SSE-KMS로 업데이트한 후 기존 객체의 암호화 유형을 변경하려는 경우 Amazon S3 Batch Operations를 사용할 수 있습니다. 객체 목록을 S3 Batch Operations에 제공하면 Batch Operations가 각각의 API 작업을 직접적으로 호출합니다. [객체 복사](batch-ops-copy-object.md) 작업을 사용하면 기존 객체를 복사하여 SSE-KMS로 암호화된 객체와 동일한 버킷에 다시 쓸 수 있습니다. 단일 배치 작업 건으로 수십억 개의 객체에서 지정된 작업을 수행할 수 있습니다. 자세한 내용은 [Batch Operations를 사용하여 대량으로 객체 작업 수행](batch-ops.md) 및 *AWS Storage Blog* 게시물 [How to retroactively encrypt existing objects in Amazon S3 using S3 Inventory, Amazon Athena, and S3 Batch Operations](https://aws.amazon.com/blogs/security/how-to-retroactively-encrypt-existing-objects-in-amazon-s3-using-s3-inventory-amazon-athena-and-s3-batch-operations/)를 참조하세요.

객체 생성 REST API를 사용하여 서버 측 암호화를 구성하려면 `x-amz-server-side-encryption` 요청 헤더를 제공해야 합니다. REST API에 대한 정보는 [REST API 사용](specifying-s3-encryption.md#SSEUsingRESTAPI) 섹션을 참조하세요.

다음 Amazon S3 API는 이러한 헤더를 지원합니다.
+ **PUT 작업** - `PUT` API를 사용하여 데이터를 업로드할 때 요청 헤더를 지정합니다. 자세한 내용은 [PUT Object](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html) 섹션을 참조하세요.
+ **멀티파트 업로드 시작** – 멀티파트 업로드 API 작업을 사용하여 대용량 객체를 업로드할 때 시작 요청에 헤더를 지정합니다. 자세한 내용은 [멀티파트 업로드 시작](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadInitiate.html)을 참조하세요.
+ **COPY 작업** - 객체를 복사할 때 소스 객체 및 대상 객체가 둘 다 있습니다. 자세한 내용은 [PUT Object - Copy](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectCOPY.html)를 참조하세요.

**참고**  
`POST` 작업을 사용하여 객체를 업로드할 경우에는 요청 헤더를 제공하는 대신 양식 필드에 동일한 정보를 제공합니다. 자세한 내용은 [POST Object](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html) 섹션을 참조하세요.

AWS SDK 또한 서버 측 암호화를 요청하는 데 사용할 수 있는 래퍼 API를 제공하며, AWS Management Console을 사용하여 객체를 업로드하고 서버 측 암호화를 요청할 수도 있습니다.

더 일반적인 내용은 **AWS Key Management Service 개발자 안내서의 [AWS KMS 개념](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html)을 참조하십시오.

**Topics**
+ [

## 서버 측 암호화를 위한 API 지원
](#APISupportforServer-SideEncryption)
+ [

# Amazon S3 관리형 키를 사용한 서버 측 암호화(SSE-S3) 지정
](specifying-s3-encryption.md)

# Amazon S3 관리형 키를 사용한 서버 측 암호화(SSE-S3) 지정
<a name="specifying-s3-encryption"></a>

모든 Amazon S3 버킷에는 기본적으로 암호화가 구성되어 있으며 S3 버킷에 업로드되는 신규 객체는 모두 저장 시 자동으로 암호화됩니다. Amazon S3 관리형 키(SSE-S3)를 사용한 서버 측 암호화가 Amazon S3 내 모든 버킷의 기본 암호화 구성입니다. 다른 유형의 암호화를 사용하려면 S3 `PUT` 요청에 사용할 서버 측 암호화 유형을 지정하거나 대상 버킷에 기본 암호화 구성을 업데이트할 수 있습니다.

`PUT` 요청에 다른 암호화 유형을 지정하려는 경우 AWS Key Management Service(AWS KMS) 키를 사용한 서버 측 암호화(SSE-KMS), AWS KMS 키를 사용한 이중 계층 서버 측 암호화(DSSE-KMS) 또는 고객 제공 키를 사용한 서버 측 암호화 (SSE-C)를 사용할 수 있습니다. 대상 버킷에 다른 기본 암호화 구성을 설정하려는 경우 SSE-KMS 또는 DSSE-KMS를 사용할 수 있습니다.

범용 버킷의 기본 암호화 구성을 변경하는 방법에 대한 자세한 내용은 [기본 암호화 구성](default-bucket-encryption.md) 섹션을 참조하세요.

버킷의 기본 암호화 구성을 SSE-KMS로 변경해도 버킷에 있는 기존 Amazon S3 객체의 암호화 유형은 변경되지 않습니다. 기본 암호화 구성을 SSE-KMS로 업데이트한 후 기존 객체의 암호화 유형을 변경하려는 경우 Amazon S3 Batch Operations를 사용할 수 있습니다. 객체 목록을 S3 Batch Operations에 제공하면 Batch Operations가 각각의 API 작업을 직접적으로 호출합니다. [객체 복사](batch-ops-copy-object.md) 작업을 사용하면 기존 객체를 복사하여 SSE-KMS로 암호화된 객체와 동일한 버킷에 다시 쓸 수 있습니다. 단일 배치 작업 건으로 수십억 개의 객체에서 지정된 작업을 수행할 수 있습니다. 자세한 내용은 [Batch Operations를 사용하여 대량으로 객체 작업 수행](batch-ops.md) 및 *AWS Storage Blog* 게시물 [How to retroactively encrypt existing objects in Amazon S3 using S3 Inventory, Amazon Athena, and S3 Batch Operations](https://aws.amazon.com/blogs/security/how-to-retroactively-encrypt-existing-objects-in-amazon-s3-using-s3-inventory-amazon-athena-and-s3-batch-operations/)를 참조하세요.

S3 콘솔, REST API, AWS SDK 및 AWS Command Line Interface(AWS CLI)를 사용하여 SSE-S3를 지정할 수 있습니다. 자세한 내용은 [Amazon S3 버킷에 대한 기본 서버 측 암호화 동작 설정](bucket-encryption.md) 섹션을 참조하세요.

## S3 콘솔 사용
<a name="add-object-encryption-s3"></a>

이 주제에서는 AWS Management Console을 사용하여 객체 암호화의 유형을 설정하거나 변경하는 방법을 설명합니다. 콘솔을 사용하여 객체를 복사할 경우 Amazon S3는 원본 그대로 객체를 복사합니다. 즉, 소스 객체가 암호화된 상태이면 대상 객체도 암호화됩니다. 콘솔을 사용하여 객체에 대한 암호화를 추가하거나 변경할 수 있습니다.

**참고**  
객체의 용량이 5GB 미만인 경우 객체의 암호화를 변경할 수 있습니다. 객체가 5GB보다 큰 경우, 객체의 암호화를 변경하려면 [AWS CLI](mpu-upload-object.md#UsingCLImpUpload) 또는 [AWS SDK](CopyingObjectsMPUapi.md)를 사용해야 합니다.
객체의 암호화를 변경하는 데 필요한 추가 권한 목록은 [Amazon S3 API 작업에 필요한 권한](using-with-s3-policy-actions.md) 섹션을 참조하세요. 이 권한을 부여하는 정책의 예시는 [Amazon S3의 ID 기반 정책 예시](example-policies-s3.md) 단원을 참조하세요.
객체 암호화를 변경하면 새 객체가 생성되어 이전 객체를 대체합니다. S3 버전 관리가 사용 설정된 경우 객체의 새 버전이 생성되고 기존 객체는 이전 버전이 됩니다. 또한 속성을 변경하는 역할도 새 객체(또는 객체 버전)의 소유자가 됩니다.

**객체에 대한 암호화를 변경하는 방법**

1. AWS Management Console에 로그인한 후 [https://console.aws.amazon.com/s3/](https://console.aws.amazon.com/s3/)에서 S3 콘솔을 엽니다.

1. 탐색 창에서 **버킷**을 선택하고 **범용 버킷** 탭을 선택합니다. 변경할 객체가 포함된 Amazon S3 버킷 또는 폴더로 이동합니다.

1. 변경하려는 객체의 확인란을 선택합니다.

1. **작업** 메뉴에 표시되는 옵션 목록에서 **서버 측 암호화 편집**을 선택합니다.

1. **서버 측 암호화** 섹션으로 스크롤합니다.

1. **암호화 설정**에서 **버킷 기본 암호화 설정 사용** 또는 **기본 암호화에 버킷 설정 재정의**를 선택합니다.

1. **기본 암호화에 버킷 설정 재정의**를 선택한 경우 다음과 같은 암호화 설정을 구성해야 합니다.

   1. **암호화 유형**에서 **Amazon S3 관리형 키를 사용한 서버 측 암호화(SSE-S3)**를 선택합니다. SSE-S3는 가장 강력한 블록 암호 중 하나인 256비트 Advanced Encryption Standard(AES-256)을 사용하여 각 객체를 암호화합니다. 자세한 내용은 [Amazon S3 관리형 키를 사용한 서버 측 암호화(SSE-S3) 사용](UsingServerSideEncryption.md) 섹션을 참조하세요.

1. **추가 복사 설정**에서 **소스 설정 복사**, **설정 지정 안 함** 또는 **설정 지정** 중 원하는 것을 선택합니다. **소스 설정 복사**가 기본 옵션입니다. 소스 설정 속성 없이 객체만 복사하려면 **설정 지정 안 함**을 선택합니다. 스토리지 클래스, ACL, 객체 태그, 메타데이터, 서버 측 암호화 및 추가 체크섬에 대한 설정을 지정하려면 **설정 지정**을 선택합니다.

1. [**변경 사항 저장(Save changes)**]을 선택합니다.

**참고**  
이 작업은 지정된 모든 객체에 암호화를 적용합니다. 폴더를 암호화할 때 폴더에 새 객체를 추가하기 전에 저장 작업이 완료될 때까지 기다립니다.

## REST API 사용
<a name="SSEUsingRESTAPI"></a>

새 객체를 업로드하거나 기존 객체를 복사하여 객체가 생성될 경우 요청에 `x-amz-server-side-encryption` 헤더를 추가하여 Amazon S3에서 Amazon S3 관리형 키(SSE-S3)를 사용하여 데이터를 암호화하도록 할지 지정할 수 있습니다. Amazon S3에서 지원하는 암호화 알고리즘인 `AES256`으로 헤더의 값을 설정합니다. Amazon S3는 `x-amz-server-side-encryption` 응답 헤더를 반환하여 객체가 SSE-S3를 사용하여 저장됨을 확인해 줍니다.

다음 REST 업로드 API 작업은 `x-amz-server-side-encryption` 요청 헤더를 수락합니다.
+ [PUT Object](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html)
+ [PUT Object - Copy](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectCOPY.html)
+ [POST Object](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html)
+ [멀티파트 업로드 시작](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadInitiate.html)

멀티파트 업로드 API 작업을 사용하여 대형 객체를 업로드할 경우 Initiate Multipart Upload 요청에 `x-amz-server-side-encryption` 헤더를 추가하여 서버 측 암호화를 지정할 수 있습니다. 기존 객체를 복사할 때 소스 객체의 암호화 여부에 관계없이 명시적으로 서버 측 암호화를 요청하지 않는 한 대상 객체는 암호화되지 않습니다.

객체가 SSE-S3를 사용하여 저장될 경우 다음 REST API 작업의 응답 헤더는 `x-amz-server-side-encryption` 헤더를 반환합니다.
+ [PUT Object](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html)
+ [PUT Object - Copy](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectCOPY.html)
+ [POST Object](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html)
+ [멀티파트 업로드 시작](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadInitiate.html)
+ [파트 업로드](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadUploadPart.html)
+ [Upload Part - Copy](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadUploadPartCopy.html)
+ [멀티파트 업로드 완료](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadComplete.html)
+ [Get Object](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectGET.html)
+ [Head Object](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectHEAD.html)

**참고**  
객체가 SSE-S3를 사용할 경우 `GET` 요청 및 `HEAD` 요청에 대해 암호화 요청 헤더를 전송하지 마십시오. 전송할 경우 HTTP 상태 코드 400(잘못된 요청) 오류가 발생합니다.

## AWS SDK 사용
<a name="s3-using-sdks"></a>

AWS SDK를 사용할 때 Amazon S3가 Amazon S3 관리형 암호화 키(SSE-S3)를 통한 서버 측 암호화를 사용하도록 요청할 수 있습니다. 이 섹션에서는 여러 언어로 AWS SDK를 사용한 예제를 제공합니다. 다른 SDK에 대한 자세한 내용은 [샘플 코드 및 라이브러리](https://aws.amazon.com/code) 섹션을 참조하세요.

------
#### [ Java ]

AWS SDK for Java를 사용하여 객체를 업로드할 때 SSE-S3를 사용하여 객체를 암호화할 수 있습니다. 서버 측 암호화를 요청하려면 `ObjectMetadata`의 `PutObjectRequest` 속성을 사용하여 `x-amz-server-side-encryption` 요청 헤더를 설정합니다. `putObject()`의 `AmazonS3Client` 메서드를 호출할 때 Amazon S3에서는 데이터를 암호화해 저장합니다.

멀티파트 업로드 API 작업을 사용하여 객체를 업로드할 때도 SSE-S3 암호화를 요청할 수 있습니다.
+ 상위 수준 멀티파트 업로드 API 작업을 사용하는 경우 `TransferManager` 메서드를 사용하여 객체를 업로드할 때 객체에 서버 측 암호화를 적용합니다. `ObjectMetadata`를 파라미터로 사용하는 모든 업로드 메서드를 사용할 수 있습니다. 자세한 내용은 [멀티파트 업로드를 사용한 객체 업로드](mpu-upload-object.md) 섹션을 참조하세요.
+ 하위 수준 멀티파트 업로드 API 작업을 사용하는 경우 멀티파트 업로드를 시작할 때 서버 측 암호화를 지정합니다. `ObjectMetadata` 메서드를 호출하여 `InitiateMultipartUploadRequest.setObjectMetadata()` 속성을 추가합니다. 자세한 내용은 [AWS SDK 사용(하위 수준 API)](mpu-upload-object.md#mpu-upload-low-level) 섹션을 참조하세요.

객체의 암호화 상태는 직접 변경할 수 없습니다(암호화되지 않은 객체 암호화 또는 암호화된 객체 암호 해독). 객체의 암호화 상태를 변경하려면 객체를 복사한 다음 사본에 대해 원하는 암호화 상태를 지정한 후 원본 객체를 삭제합니다. Amazon S3에서는 서버 측 암호화를 명시적으로 요청한 경우에만 객체의 사본을 암호화합니다. Java API를 통해 객체 사본 암호화를 요청하려면 `ObjectMetadata` 속성을 사용하여 `CopyObjectRequest`에서 서버 측 암호화를 지정합니다.

**Example 예제**  
다음 예시에서는 AWS SDK for Java를 사용하여 서버 측 암호화를 설정하는 방법을 보여줍니다. 이 예제에서는 다음 작업을 수행하는 방법을 설명합니다.  
+ SSE-S3를 사용하여 새 객체를 업로드합니다.
+ 객체의 사본을 만들어 객체의 암호화 상태를 변경합니다(이 예제에서는 이전에 암호화되지 않은 객체를 암호화함).
+ 객체의 암호화 상태를 확인합니다.
서버 측 암호화에 대한 자세한 정보는 [REST API 사용](#SSEUsingRESTAPI) 섹션을 참조하십시오. 실제 예제를 작성 및 테스트하는 방법에 대한 자세한 내용은 AWS SDK for Java 개발자 안내서의 [시작하기](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/getting-started.html) 섹션을 참조하세요.  

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.SdkClientException;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.internal.SSEResultBase;
import com.amazonaws.services.s3.model.*;

import java.io.ByteArrayInputStream;

public class SpecifyServerSideEncryption {

    public static void main(String[] args) {
        Regions clientRegion = Regions.DEFAULT_REGION;
        String bucketName = "*** Bucket name ***";
        String keyNameToEncrypt = "*** Key name for an object to upload and encrypt ***";
        String keyNameToCopyAndEncrypt = "*** Key name for an unencrypted object to be encrypted by copying ***";
        String copiedObjectKeyName = "*** Key name for the encrypted copy of the unencrypted object ***";

        try {
            AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                    .withRegion(clientRegion)
                    .withCredentials(new ProfileCredentialsProvider())
                    .build();

            // Upload an object and encrypt it with SSE.
            uploadObjectWithSSEEncryption(s3Client, bucketName, keyNameToEncrypt);

            // Upload a new unencrypted object, then change its encryption state
            // to encrypted by making a copy.
            changeSSEEncryptionStatusByCopying(s3Client,
                    bucketName,
                    keyNameToCopyAndEncrypt,
                    copiedObjectKeyName);
        } catch (AmazonServiceException e) {
            // The call was transmitted successfully, but Amazon S3 couldn't process
            // it, so it returned an error response.
            e.printStackTrace();
        } catch (SdkClientException e) {
            // Amazon S3 couldn't be contacted for a response, or the client
            // couldn't parse the response from Amazon S3.
            e.printStackTrace();
        }
    }

    private static void uploadObjectWithSSEEncryption(AmazonS3 s3Client, String bucketName, String keyName) {
        String objectContent = "Test object encrypted with SSE";
        byte[] objectBytes = objectContent.getBytes();

        // Specify server-side encryption.
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setContentLength(objectBytes.length);
        objectMetadata.setSSEAlgorithm(ObjectMetadata.AES_256_SERVER_SIDE_ENCRYPTION);
        PutObjectRequest putRequest = new PutObjectRequest(bucketName,
                keyName,
                new ByteArrayInputStream(objectBytes),
                objectMetadata);

        // Upload the object and check its encryption status.
        PutObjectResult putResult = s3Client.putObject(putRequest);
        System.out.println("Object \"" + keyName + "\" uploaded with SSE.");
        printEncryptionStatus(putResult);
    }

    private static void changeSSEEncryptionStatusByCopying(AmazonS3 s3Client,
            String bucketName,
            String sourceKey,
            String destKey) {
        // Upload a new, unencrypted object.
        PutObjectResult putResult = s3Client.putObject(bucketName, sourceKey, "Object example to encrypt by copying");
        System.out.println("Unencrypted object \"" + sourceKey + "\" uploaded.");
        printEncryptionStatus(putResult);

        // Make a copy of the object and use server-side encryption when storing the
        // copy.
        CopyObjectRequest request = new CopyObjectRequest(bucketName,
                sourceKey,
                bucketName,
                destKey);
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setSSEAlgorithm(ObjectMetadata.AES_256_SERVER_SIDE_ENCRYPTION);
        request.setNewObjectMetadata(objectMetadata);

        // Perform the copy operation and display the copy's encryption status.
        CopyObjectResult response = s3Client.copyObject(request);
        System.out.println("Object \"" + destKey + "\" uploaded with SSE.");
        printEncryptionStatus(response);

        // Delete the original, unencrypted object, leaving only the encrypted copy in
        // Amazon S3.
        s3Client.deleteObject(bucketName, sourceKey);
        System.out.println("Unencrypted object \"" + sourceKey + "\" deleted.");
    }

    private static void printEncryptionStatus(SSEResultBase response) {
        String encryptionStatus = response.getSSEAlgorithm();
        if (encryptionStatus == null) {
            encryptionStatus = "Not encrypted with SSE";
        }
        System.out.println("Object encryption status is: " + encryptionStatus);
    }
}
```

------
#### [ .NET ]

객체를 업로드할 때 Amazon S3에 객체를 암호화하도록 지시할 수 있습니다. 기존 객체의 암호화 상태를 변경하기 위해서는 객체를 복사한 다음 원본 객체를 삭제합니다. 기본적으로 복사 작업은 대상 객체의 서버 측 암호화를 명시적으로 요청하는 경우에만 대상을 암호화합니다. `CopyObjectRequest`에서 SSE-S3를 지정하려면 다음을 추가합니다.

```
 ServerSideEncryptionMethod = ServerSideEncryptionMethod.AES256
```

객체를 복사하는 방법에 대한 실제 예제는 [AWS SDK 사용](copy-object.md#CopyingObjectsUsingSDKs)를 참조하세요.

다음은 객체를 업로드하는 예제입니다. 요청 시 이 예제는 Amazon S3에 객체를 암호화하도록 지시합니다. 그런 다음 객체 메타데이터를 검색해 사용된 암호화 방법을 확인합니다. 코드 예제 설정 및 실행에 대한 자세한 내용은 *AWS SDK for .NET 개발자 안내서*의 [AWS SDK for .NET 시작하기](https://docs.aws.amazon.com/sdk-for-net/latest/developer-guide/net-dg-setup.html)를 참조하세요.

```
using Amazon;
using Amazon.S3;
using Amazon.S3.Model;
using System;
using System.Threading.Tasks;

namespace Amazon.DocSamples.S3
{
    class SpecifyServerSideEncryptionTest
    {
        private const string bucketName = "*** bucket name ***";
        private const string keyName = "*** key name for object created ***";
        // Specify your bucket region (an example region is shown).
        private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2;
        private static IAmazonS3 client;

        public static void Main()
        {
            client = new AmazonS3Client(bucketRegion);
            WritingAnObjectAsync().Wait();
        }

        static async Task WritingAnObjectAsync()
        {
            try
            {
                var putRequest = new PutObjectRequest
                {
                    BucketName = bucketName,
                    Key = keyName,
                    ContentBody = "sample text",
                    ServerSideEncryptionMethod = ServerSideEncryptionMethod.AES256
                };

                var putResponse = await client.PutObjectAsync(putRequest);

                // Determine the encryption state of an object.
                GetObjectMetadataRequest metadataRequest = new GetObjectMetadataRequest
                {
                    BucketName = bucketName,
                    Key = keyName
                };
                GetObjectMetadataResponse response = await client.GetObjectMetadataAsync(metadataRequest);
                ServerSideEncryptionMethod objectEncryption = response.ServerSideEncryptionMethod;

                Console.WriteLine("Encryption method used: {0}", objectEncryption.ToString());
            }
            catch (AmazonS3Exception e)
            {
                Console.WriteLine("Error encountered ***. Message:'{0}' when writing an object", e.Message);
            }
            catch (Exception e)
            {
                Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message);
            }
        }
    }
}
```

------
#### [ PHP ]

이 주제에서는 Amazon S3에 업로드하는 객체에 SSE-S3를 추가하기 위해 AWS SDK for PHP 버전 3의 클래스를 사용하는 방법을 보여줍니다. AWS SDK for Ruby API에 대한 자세한 내용은 [AWS SDK for Ruby – 버전 2](https://docs.aws.amazon.com/sdkforruby/api/index.html)를 참조하세요.

Amazon S3에 객체를 업로드하려면 [Aws\$1S3\$1S3Client::putObject()](https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#putobject) 메서드를 사용합니다. 업로드 요청에 `x-amz-server-side-encryption` 요청 헤더를 추가하려면 다음 코드 예제에 나와 있듯이 `ServerSideEncryption` 파라미터를 `AES256` 값으로 지정합니다. 서버 측 암호화 요청에 대한 자세한 정보는 [REST API 사용](#SSEUsingRESTAPI) 섹션을 참조하세요.

```
 require 'vendor/autoload.php';

use Aws\S3\S3Client;

$bucket = '*** Your Bucket Name ***';
$keyname = '*** Your Object Key ***';

// $filepath should be an absolute path to a file on disk.
$filepath = '*** Your File Path ***';

$s3 = new S3Client([
    'version' => 'latest',
    'region'  => 'us-east-1'
]);

// Upload a file with server-side encryption.
$result = $s3->putObject([
    'Bucket'               => $bucket,
    'Key'                  => $keyname,
    'SourceFile'           => $filepath,
    'ServerSideEncryption' => 'AES256',
]);
```

이에 응답하여 Amazon S3가 객체 데이터 암호화에 사용된 암호화 알고리즘의 값과 함께 `x-amz-server-side-encryption` 헤더를 반환합니다.

멀티파트 업로드 API 작업을 사용하여 대용량 객체를 업로드할 때 업로드할 객체에 대해 다음과 같이 SSE-S3를 지정할 수 있습니다.
+ 하위 수준 멀티파트 업로드 API 작업을 사용하는 경우 [ Aws\$1S3\$1S3Client::createMultipartUpload()](https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#createmultipartupload) 메서드를 호출할 때 서버 측 암호화를 지정합니다. 요청에 `x-amz-server-side-encryption` 요청 헤더를 추가하려면 `array` 파라미터의 `ServerSideEncryption` 키를 값 `AES256`과 함께 지정합니다. 하위 수준 멀티파트 업로드 API 작업에 대한 자세한 내용은 [AWS SDK 사용(하위 수준 API)](mpu-upload-object.md#mpu-upload-low-level) 섹션을 참조하십시오.
+ 상위 수준 멀티파트 업로드 API 작업을 사용하는 경우 [CreateMultipartUpload](https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#createmultipartupload) API 작업의 `ServerSideEncryption` 파라미터를 사용하여 서버 측 암호화를 지정합니다. 상위 수준 멀티파트 업로드 API 작업과 함께 `setOption()` 메서드를 사용하는 예제는 [멀티파트 업로드를 사용한 객체 업로드](mpu-upload-object.md) 섹션을 참조하십시오.

기존 객체의 암호화 상태를 확인하려면 다음 PHP 코드 예제에 나와 있듯이 [Aws\$1S3\$1S3Client::headObject()](https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#headobject) 메서드를 호출하여 객체 메타데이터를 검색하세요.

```
 require 'vendor/autoload.php';

use Aws\S3\S3Client;

$bucket = '*** Your Bucket Name ***';
$keyname = '*** Your Object Key ***';

$s3 = new S3Client([
    'version' => 'latest',
    'region'  => 'us-east-1'
]);

// Check which server-side encryption algorithm is used.
$result = $s3->headObject([
    'Bucket' => $bucket,
    'Key'    => $keyname,
]);
echo $result['ServerSideEncryption'];
```

기존 객체의 암호화 상태를 변경하려면 [Aws\$1S3\$1S3Client::copyObject()](https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#copyobject) 메서드를 사용하여 객체를 복사하고 소스 객체를 삭제하십시오. `ServerSideEncryption` 파라미터를 `AES256` 값으로 사용하여 대상 객체의 서버 측 암호화를 명시적으로 요청하지 않는 한 기본적으로 `copyObject()`는 대상을 암호화하지 않습니다. 다음 PHP 코드 예제에서는 객체를 복사하고 복사된 객체에 서버 측 암호화를 추가합니다.

```
 require 'vendor/autoload.php';

use Aws\S3\S3Client;

$sourceBucket = '*** Your Source Bucket Name ***';
$sourceKeyname = '*** Your Source Object Key ***';

$targetBucket = '*** Your Target Bucket Name ***';
$targetKeyname = '*** Your Target Object Key ***';

$s3 = new S3Client([
    'version' => 'latest',
    'region'  => 'us-east-1'
]);

// Copy an object and add server-side encryption.
$s3->copyObject([
    'Bucket'               => $targetBucket,
    'Key'                  => $targetKeyname,
    'CopySource'           => "$sourceBucket/$sourceKeyname",
    'ServerSideEncryption' => 'AES256',
]);
```

자세한 내용은 다음 항목을 참조하세요.
+ [AWS SDK for PHPAmazon S3 Aws\$1S3\$1S3Client Class용](https://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.S3.S3Client.html) 
+ [AWS SDK for PHP 설명서](https://aws.amazon.com/documentation/sdk-for-php/)

------
#### [ Ruby ]

AWS SDK for Ruby를 사용하여 객체를 업로드하는 경우, 객체가 SSE-S3를 통해 암호화된 상태로 저장되도록 지정할 수 있습니다. 다시 객체를 읽으면 객체가 자동으로 복호화됩니다.

다음 AWS SDK for Ruby 버전 3 예시는 파일을 Amazon S3에 업로드한 후 암호화하여 저장하는 방법을 보여줍니다.

```
require 'aws-sdk-s3'

# Wraps Amazon S3 object actions.
class ObjectPutSseWrapper
  attr_reader :object

  # @param object [Aws::S3::Object] An existing Amazon S3 object.
  def initialize(object)
    @object = object
  end

  def put_object_encrypted(object_content, encryption)
    @object.put(body: object_content, server_side_encryption: encryption)
    true
  rescue Aws::Errors::ServiceError => e
    puts "Couldn't put your content to #{object.key}. Here's why: #{e.message}"
    false
  end
end

# Example usage:
def run_demo
  bucket_name = "amzn-s3-demo-bucket"
  object_key = "my-encrypted-content"
  object_content = "This is my super-secret content."
  encryption = "AES256"

  wrapper = ObjectPutSseWrapper.new(Aws::S3::Object.new(bucket_name, object_content))
  return unless wrapper.put_object_encrypted(object_content, encryption)

  puts "Put your content into #{bucket_name}:#{object_key} and encrypted it with #{encryption}."
end

run_demo if $PROGRAM_NAME == __FILE__
```

다음 코드 예제는 기존 객체의 암호화 상태를 확인하는 방법을 보여줍니다.

```
require 'aws-sdk-s3'

# Wraps Amazon S3 object actions.
class ObjectGetEncryptionWrapper
  attr_reader :object

  # @param object [Aws::S3::Object] An existing Amazon S3 object.
  def initialize(object)
    @object = object
  end

  # Gets the object into memory.
  #
  # @return [Aws::S3::Types::GetObjectOutput, nil] The retrieved object data if successful; otherwise nil.
  def object
    @object.get
  rescue Aws::Errors::ServiceError => e
    puts "Couldn't get object #{@object.key}. Here's why: #{e.message}"
  end
end

# Example usage:
def run_demo
  bucket_name = "amzn-s3-demo-bucket"
  object_key = "my-object.txt"

  wrapper = ObjectGetEncryptionWrapper.new(Aws::S3::Object.new(bucket_name, object_key))
  obj_data = wrapper.get_object
  return unless obj_data

  encryption = obj_data.server_side_encryption.nil? ? 'no' : obj_data.server_side_encryption
  puts "Object #{object_key} uses #{encryption} encryption."
end

run_demo if $PROGRAM_NAME == __FILE__
```

Amazon S3에 저장된 객체에 서버 측 암호화가 사용되지 않은 경우 메서드는 `null`을 반환합니다.

기존 객체의 암호화 상태를 변경하려면 객체를 복사한 다음 원본 객체를 삭제합니다. 기본적으로 명시적으로 서버 측 암호화를 요청하지 않는 한, 복사 메서드는 대상을 암호화하지 않습니다. 다음 Ruby 코드 예시와 같이 옵션 해시 인수에 `server_side_encryption` 값을 지정하여 대상 객체 암호화를 요청할 수 있습니다. 이 코드 예시는 객체를 복사하고 복사본을 SSE-S3로 암호화하는 방법을 보여줍니다.

```
require 'aws-sdk-s3'

# Wraps Amazon S3 object actions.
class ObjectCopyEncryptWrapper
  attr_reader :source_object

  # @param source_object [Aws::S3::Object] An existing Amazon S3 object. This is used as the source object for
  #                                        copy actions.
  def initialize(source_object)
    @source_object = source_object
  end

  # Copy the source object to the specified target bucket, rename it with the target key, and encrypt it.
  #
  # @param target_bucket [Aws::S3::Bucket] An existing Amazon S3 bucket where the object is copied.
  # @param target_object_key [String] The key to give the copy of the object.
  # @return [Aws::S3::Object, nil] The copied object when successful; otherwise, nil.
  def copy_object(target_bucket, target_object_key, encryption)
    @source_object.copy_to(bucket: target_bucket.name, key: target_object_key, server_side_encryption: encryption)
    target_bucket.object(target_object_key)
  rescue Aws::Errors::ServiceError => e
    puts "Couldn't copy #{@source_object.key} to #{target_object_key}. Here's why: #{e.message}"
  end
end

# Example usage:
def run_demo
  source_bucket_name = "amzn-s3-demo-bucket1"
  source_key = "my-source-file.txt"
  target_bucket_name = "amzn-s3-demo-bucket2"
  target_key = "my-target-file.txt"
  target_encryption = "AES256"

  source_bucket = Aws::S3::Bucket.new(source_bucket_name)
  wrapper = ObjectCopyEncryptWrapper.new(source_bucket.object(source_key))
  target_bucket = Aws::S3::Bucket.new(target_bucket_name)
  target_object = wrapper.copy_object(target_bucket, target_key, target_encryption)
  return unless target_object

  puts "Copied #{source_key} from #{source_bucket_name} to #{target_object.bucket_name}:#{target_object.key} and "\
       "encrypted the target with #{target_object.server_side_encryption} encryption."
end

run_demo if $PROGRAM_NAME == __FILE__
```

------

## AWS CLI 사용
<a name="sse-s3-aws-cli"></a>

AWS CLI를 사용하여 객체를 업로드할 때 SSE-S3를 지정하려면 다음 예시를 사용합니다.

```
aws s3api put-object --bucket amzn-s3-demo-bucket1 --key object-key-name --server-side-encryption AES256  --body file path
```

자세한 내용은 *AWS CLI 참조*에서 [put-object](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/put-object.html)를 참조하십시오. AWS CLI를 사용하여 객체를 복사할 때 SSE-S3를 지정하려면 [copy-object](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/copy-object.html)를 참조하십시오.

## 사용CloudFormation
<a name="ss3-s3-cfn"></a>

CloudFormation을 사용하여 암호화를 설정하는 방법의 예제는 **AWS CloudFormation 사용 설명서의 `AWS::S3::Bucket ServerSideEncryptionRule`에 있는 [기본 암호화로 버킷 생성](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket-serversideencryptionrule.html#aws-properties-s3-bucket-serversideencryptionrule--examples--Create_a_bucket_with_default_encryption) 및 [S3 버킷 키로 AWS KMS 서버 측 암호화를 사용하여 버킷 생성](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket-serversideencryptionrule.html#aws-properties-s3-bucket-serversideencryptionrule--examples--Create_a_bucket_using_AWS_KMS_server-side_encryption_with_an_S3_Bucket_Key)을 참조하십시오.