

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

# 체크섬을 통한 데이터 무결성 보호
<a name="s3-checksums"></a>

Amazon Simple Storage Service(S3)는 객체를 업로드할 때 체크섬을 지정하는 기능을 제공합니다. 체크섬을 지정하면 객체와 함께 저장되며 객체를 다운로드할 때 유효성을 검사할 수 있습니다.

체크섬은 파일을 전송할 때 데이터 무결성을 한층 더 강화합니다. 체크섬을 사용하면 수신된 파일이 원본 파일과 일치하는지 확인하여 데이터 일관성을 확인할 수 있습니다. Amazon S3의 체크섬에 대한 자세한 내용은 [지원되는 알고리즘](https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#using-additional-checksums)을 포함한 [Amazon Simple Storage Service 사용 설명서](https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html)를 참조하세요.

필요에 가장 적합한 알고리즘을 유연하게 선택하고 SDK가 체크섬을 계산하도록 할 수 있습니다. 또는 지원되는 알고리즘 중 하나를 사용하여 미리 계산된 체크섬 값을 제공할 수 있습니다.

**참고**  
 AWS SDK for Java 2.x의 버전 2.30.0부터 SDK는 업로드에 대한 `CRC32` 체크섬을 자동으로 계산하여 기본 무결성 보호를 제공합니다. 사전 계산된 체크섬 값을 제공하지 않거나 SDK가 체크섬을 계산하는 데 사용해야 하는 알고리즘을 지정하지 않은 경우 SDK는이 체크섬을 계산합니다.   
또한 SDK는 [AWS SDK 및 도구 참조 안내서](https://docs.aws.amazon.com/sdkref/latest/guide/feature-dataintegrity.html)에서 확인할 수 있고 외부에서 설정할 수 있는 데이터 무결성 보호에 대한 전역 설정을 지원합니다.

체크섬은 객체 업로드와 객체 다운로드라는 두 가지 요청 단계로 설명합니다.

## 객체 업로드
<a name="use-service-S3-checksum-upload"></a>

 `putObject` 메서드를 사용하여 객체를 업로드하고 체크섬 알고리즘을 제공하면 SDK가 지정된 알고리즘의 체크섬을 계산합니다.

다음 코드 조각은 `SHA256` 체크섬이 있는 객체를 업로드하라는 요청을 보여줍니다. SDK는 요청을 보내면 `SHA256` 체크섬을 계산하고 객체를 업로드합니다. Amazon S3는 체크섬을 계산하고 SDK에서 제공하는 체크섬과 비교하여 콘텐츠의 무결성을 확인합니다. Amazon S3는 객체와 함께 체크섬을 저장합니다.

```
public void putObjectWithChecksum() {
        s3Client.putObject(b -> b
                .bucket(bucketName)
                .key(key)
                .checksumAlgorithm(ChecksumAlgorithm.SHA256),
            RequestBody.fromString("This is a test"));
}
```

요청에 체크섬 알고리즘을 제공하지 않는 경우 체크섬 동작은 다음 표와 같이 사용하는 SDK 버전에 따라 달라집니다.

**체크섬 알고리즘이 제공되지 않은 경우 체크섬 동작**


| Java SDK 버전 | 체크섬 동작 | 
| --- | --- | 
| 2.30.0 이하 | SDK는 CRC 기반 체크섬을 자동으로 계산하여 요청에 제공하지 않습니다. | 
| 2.30.0 이상 | SDK는 `CRC32` 알고리즘을 사용하여 체크섬을 계산하고 요청에 제공합니다. Amazon S3는 자체 `CRC32` 체크섬을 계산하여 전송의 무결성을 확인하고 이를 SDK에서 제공하는 체크섬과 비교합니다. 체크섬이 일치하면 체크섬이 객체와 함께 저장됩니다. | 

### 미리 계산된 체크섬 값 사용
<a name="use-service-S3-checksum-upload-pre"></a>

요청과 함께 제공되는 사전 계산된 체크섬 값은 SDK의 자동 계산을 비활성화하고 제공된 값을 대신 사용합니다.

다음 예제에서는 사전 계산된 SHA256 체크섬이 있는 요청을 보여줍니다.

```
    public void putObjectWithPrecalculatedChecksum(String filePath) {
        String checksum = calculateChecksum(filePath, "SHA-256");

        s3Client.putObject((b -> b
                .bucket(bucketName)
                .key(key)
                .checksumSHA256(checksum)),
            RequestBody.fromFile(Paths.get(filePath)));
    }
```

Amazon S3에서 체크섬 값이 지정된 알고리즘에 대해 올바르지 않다고 판단하면 서비스는 오류 응답을 반환합니다.

### 멀티파트 업로드
<a name="use-service-S3-checksum-upload-multi"></a>

멀티파트 업로드에 체크섬을 사용할 수도 있습니다.

 Java 2.x용 SDK는 멀티파트 업로드에 체크섬을 사용하는 두 가지 옵션을 제공합니다. 첫 번째 옵션은 `S3TransferManager`를 사용합니다.

다음 전송 관리자 예제는 업로드를 위한 SHA1 알고리즘을 지정합니다.

```
    public void multipartUploadWithChecksumTm(String filePath) {
        S3TransferManager transferManager = S3TransferManager.create();
        UploadFileRequest uploadFileRequest = UploadFileRequest.builder()
            .putObjectRequest(b -> b
                .bucket(bucketName)
                .key(key)
                .checksumAlgorithm(ChecksumAlgorithm.SHA1))
            .source(Paths.get(filePath))
            .build();
        FileUpload fileUpload = transferManager.uploadFile(uploadFileRequest);
        fileUpload.completionFuture().join();
        transferManager.close();
    }
```

업로드에 전송 관리자를 사용할 때 체크섬 알고리즘을 제공하지 않으면 SDK는 `CRC32` 알고리즘을 기반으로 체크섬을 자동으로 계산합니다. SDK는 SDK의 모든 버전에서 이 계산을 수행합니다.

두 번째 옵션은 [`S3Client` API](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Client.html)(또는 [`S3AsyncClient` API](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClient.html))를 사용하여 멀티파트 업로드를 수행합니다. 이 접근법으로 추가 체크섬을 지정하는 경우 업로드를 시작할 때 사용할 알고리즘을 지정해야 합니다. 또한 각 파트 요청에 대한 알고리즘을 지정하고 업로드 후 각 파트에 대해 계산된 체크섬을 제공해야 합니다.

```
    public void multipartUploadWithChecksumS3Client(String filePath) {
        ChecksumAlgorithm algorithm = ChecksumAlgorithm.CRC32;

        // Initiate the multipart upload.
        CreateMultipartUploadResponse createMultipartUploadResponse = s3Client.createMultipartUpload(b -> b
            .bucket(bucketName)
            .key(key)
            .checksumAlgorithm(algorithm)); // Checksum specified on initiation.
        String uploadId = createMultipartUploadResponse.uploadId();

        // Upload the parts of the file.
        int partNumber = 1;
        List<CompletedPart> completedParts = new ArrayList<>();
        ByteBuffer bb = ByteBuffer.allocate(1024 * 1024 * 5); // 5 MB byte buffer

        try (RandomAccessFile file = new RandomAccessFile(filePath, "r")) {
            long fileSize = file.length();
            long position = 0;
            while (position < fileSize) {
                file.seek(position);
                long read = file.getChannel().read(bb);

                bb.flip(); // Swap position and limit before reading from the buffer.
                UploadPartRequest uploadPartRequest = UploadPartRequest.builder()
                    .bucket(bucketName)
                    .key(key)
                    .uploadId(uploadId)
                    .checksumAlgorithm(algorithm) // Checksum specified on each part.
                    .partNumber(partNumber)
                    .build();

                UploadPartResponse partResponse = s3Client.uploadPart(
                    uploadPartRequest,
                    RequestBody.fromByteBuffer(bb));

                CompletedPart part = CompletedPart.builder()
                    .partNumber(partNumber)
                    .checksumCRC32(partResponse.checksumCRC32()) // Provide the calculated checksum.
                    .eTag(partResponse.eTag())
                    .build();
                completedParts.add(part);

                bb.clear();
                position += read;
                partNumber++;
            }
        } catch (IOException e) {
            System.err.println(e.getMessage());
        }

        // Complete the multipart upload.
        s3Client.completeMultipartUpload(b -> b
            .bucket(bucketName)
            .key(key)
            .uploadId(uploadId)
            .multipartUpload(CompletedMultipartUpload.builder().parts(completedParts).build()));
    }
```

[전체 예제 코드](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javav2/example_code/s3/src/main/java/com/example/s3/PerformMultiPartUpload.java) 및 [테스트](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javav2/example_code/s3/src/test/java/com/example/s3/PerformMultiPartUploadTests.java) 코드는 GitHub 코드 예제 저장소에 있습니다.

## 객체 다운로드
<a name="use-service-S3-checksum-download"></a>

[getObject](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Client.html#getObject(software.amazon.awssdk.services.s3.model.GetObjectRequest)) 메서드를 사용하여 객체를 다운로드하면, `GetObjectRequest`용 빌더의 `checksumMode` 메서드가 `ChecksumMode.ENABLED`로 설정된 경우. 

다음 스니펫의 요청은 체크섬을 계산하고 값을 비교하여 응답의 체크섬을 검증하도록 SDK에 지시합니다.

```
    public GetObjectResponse getObjectWithChecksum() {
        return s3Client.getObject(b -> b
                        .bucket(bucketName)
                        .key(key)
                        .checksumMode(ChecksumMode.ENABLED))
                .response();
    }
```

**참고**  
체크섬과 함께 객체를 업로드하지 않은 경우 검증이 수행되지 않습니다.

## 기타 체크섬 계산 옵션
<a name="S3-checsum-calculation-options"></a>

**참고**  
전송된 데이터의 데이터 무결성을 확인하고 전송 오류를 식별하려면 사용자가 체크섬 계산 옵션에 대한 SDK 기본 설정을 유지하는 것이 좋습니다. 기본적으로 SDK는 `PutObject` 및 `GetObject`를 포함한 많은 S3 작업에 대해 이 중요한 검사를 추가합니다.

그러나 Amazon S3를 사용하려면 최소한의 체크섬 확인이 필요한 경우 기본 구성 설정을 변경하여 많은 검사를 비활성화할 수 있습니다.

### 필요하지 않은 경우 자동 체크섬 계산 비활성화
<a name="S3-minimize-checksum-calc-global"></a>

`PutObject` 및 `GetObject`와 같이 이를 지원하는 작업에 대해 SDK에서 자동 체크섬 계산을 비활성화할 수 있습니다. 그러나 일부 S3 작업에는 체크섬 계산이 필요하므로 이러한 작업에 대한 체크섬 계산을 비활성화할 수 없습니다.

SDK는 요청의 페이로드와 응답의 페이로드에 대한 체크섬 계산을 위한 별도의 설정을 제공합니다.

다음 목록은 다양한 범위에서 체크섬 계산을 최소화하는 데 사용할 수 있는 설정을 설명합니다.
+ **모든 애플리케이션 범위** - 환경 변수 또는 공유 AWS `config` 및 `credentials` 파일의 프로파일에서 설정을 변경하면 모든 애플리케이션에서 이러한 설정을 사용할 수 있습니다. 애플리케이션 또는 서비스 클라이언트 범위에서 재정의되지 않는 한 이러한 설정은 모든 AWS SDK 애플리케이션의 모든 서비스 클라이언트에 영향을 줍니다.
  + 프로파일에 설정을 추가합니다.

    ```
    [default]
    request_checksum_calculation = WHEN_REQUIRED
    response_checksum_validation = WHEN_REQUIRED
    ```
  + 환경 변수를 추가합니다.

    ```
    AWS_REQUEST_CHECKSUM_CALCULATION=WHEN_REQUIRED
    AWS_RESPONSE_CHECKSUM_VALIDATION=WHEN_REQUIRED
    ```
+ **현재 애플리케이션 범위** - Java 시스템 속성(`aws.requestChecksumCalculation`)을 `WHEN_REQUIRED`로 설정하여 체크섬 계산을 제한할 수 있습니다. 응답에 해당하는 시스템 속성은 `aws.responseChecksumValidation`입니다.

  이러한 설정은 서비스 클라이언트를 만드는 중에 재정의되지 않는 한 애플리케이션의 모든 SDK 서비스 클라이언트에 영향을 줍니다.

  애플리케이션 시작 시 시스템 속성을 설정합니다.

  ```
  import software.amazon.awssdk.core.SdkSystemSetting;
  import software.amazon.awssdk.core.checksums.RequestChecksumCalculation;
  import software.amazon.awssdk.core.checksums.ResponseChecksumValidation;
  import software.amazon.awssdk.services.s3.S3Client;
  
  class DemoClass {
      public static void main(String[] args) {
  
          System.setProperty(SdkSystemSetting.AWS_REQUEST_CHECKSUM_CALCULATION.property(), // Resolves to "aws.requestChecksumCalculation".
                  "WHEN_REQUIRED");
          System.setProperty(SdkSystemSetting.AWS_RESPONSE_CHECKSUM_VALIDATION.property(), // Resolves to "aws.responseChecksumValidation".
                  "WHEN_REQUIRED");
  
          S3Client s3Client = S3Client.builder().build();
  
          // Use s3Client.
      }
  }
  ```
+ **단일 S3 서비스 클라이언트 범위** - 빌더 메서드를 사용하여 최소 체크섬 양을 계산하도록 단일 S3 서비스 클라이언트를 구성할 수 있습니다.

  ```
  import software.amazon.awssdk.core.checksums.RequestChecksumCalculation;
  import software.amazon.awssdk.services.s3.S3Client;
  
  public class RequiredChecksums {
      public static void main(String[] args) {
          S3Client s3 = S3Client.builder()
                  .requestChecksumCalculation(RequestChecksumCalculation.WHEN_REQUIRED)
                  .responseChecksumValidation(ResponseChecksumValidation.WHEN_REQUIRED)
                  .build();
  
          // Use s3Client. 
      }
  // ...
  }
  ```

### 간소화된 MD5 호환성을 위해 `LegacyMd5Plugin` 사용
<a name="S3-checksum-legacy-md5"></a>

버전 2.30.0의 CRC32 체크섬 동작 릴리스와 함께 SDK는 필요한 작업에 대한 MD5 체크섬 계산을 중단했습니다.

S3 작업에 레거시 MD5 체크섬 동작이 필요한 경우 SDK 버전 2.31.32에서 릴리스된 `LegacyMd5Plugin`을 사용할 수 있습니다.

`LegacyMd5Plugin`은 레거시 MD5 체크섬 동작에 의존하는 애플리케이션과의 호환성을 유지해야 할 때 유용합니다. 특히 S3A 파일 시스템 커넥터(Apache Spark, Iceberg)와 함께 사용되는 서드 파티 S3 호환 스토리지 공급자와 함께 작업할 때 유용합니다.

`LegacyMd5Plugin`을 사용하려면 S3 클라이언트 빌더에 추가합니다.

```
// For synchronous S3 client.
S3Client s3Client = S3Client.builder()
                           .addPlugin(LegacyMd5Plugin.create())
                           .build();

// For asynchronous S3 client.
S3AsyncClient asyncClient = S3AsyncClient.builder()
                                       .addPlugin(LegacyMd5Plugin.create())
                                       .build();
```

체크섬이 필요한 작업에 MD5 체크섬을 추가하고 체크섬을 지원하지만 필요하지 않은 작업에 대한 SDK 기본 체크섬 추가를 건너뛰려면 `ClientBuilder` 옵션 `requestChecksumCalculation` 및 `responseChecksumValidation`을 `WHEN_REQUIRED`로 사용할 수 있습니다. 이렇게 하면 체크섬이 필요한 작업에만 SDK 기본 체크섬이 추가됩니다.

```
// Use the `LegacyMd5Plugin` with `requestChecksumCalculation` and `responseChecksumValidation` set to WHEN_REQUIRED.
S3AsyncClient asyncClient = S3AsyncClient.builder()
                                       .addPlugin(LegacyMd5Plugin.create())
                                       .requestChecksumCalculation(RequestChecksumCalculation.WHEN_REQUIRED)
                                       .responseChecksumValidation(ResponseChecksumValidation.WHEN_REQUIRED)
                                       .build();
```

이 구성은 최신 체크섬 알고리즘을 완전히 지원하지는 않지만 특정 작업에 대해 여전히 MD5 체크섬이 필요한 서드 파티 S3 호환 스토리지 시스템으로 작업할 때 특히 유용합니다.