S3 SSE-KMS 적용하기

오형상·2024년 12월 4일
0

Ficket

목록 보기
15/27

Ficket 프로젝트는 얼굴 인식 기반 티켓팅 프로젝트로, 사용자 얼굴 이미지를 안전하게 보관하기 위한 방안을 고민했습니다. 민감한 데이터를 다루는 만큼 보안이 가장 중요한 요소였고, 데이터 암호화와 접근 제어를 위해 S3의 SSE-KMS(Server-Side Encryption with AWS Key Management Service)를 사용하기로 했습니다. 이 글에서는 S3 버킷에 KMS를 활용한 서버 사이드 암호화를 설정하고, Python으로 파일을 업로드하는 방법을 다룹니다.

사전 준비

AWS 계정과 기본 S3 환경이 설정되어 있어야 하며, IAM 권한을 적절히 구성해야 합니다.


KMS 키 생성

먼저, KMS 키를 생성합니다.

1) 키 구성

2) 레이블 추가

3) 키 관리 권한 정의

4) 키 사용 권한 정의


IAM 권한 수정

이미 S3 권한이 존재한다면, KMS 권한을 추가로 설정합니다.

아래는 KMS 권한 JSON 예제입니다:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "kms:Encrypt",
                "kms:Decrypt",
                "kms:GenerateDataKey",
                "kms:DescribeKey"
            ],
            "Resource": "{생성한 KMS ARN 값}"
        }
    ]
}


S3 설정

S3 버킷에 기본 암호화를 설정합니다.

  1. 버킷에 들어가서 속성 탭을 선택합니다.
  2. 기본 암호화 섹션을 편집하여 KMS 키를 설정합니다.


AWS SDK (w. Python)

1) 파일 업로드 함수

아래는 S3에 파일을 업로드하는 Python 코드입니다. 이 코드는 파일을 KMS로 암호화하여 안전하게 저장합니다.

import uuid
from config.s3_config import s3, bucket_name, kms_key_id

def upload_file_to_s3(file, folder="faces"):
    """S3에 파일 업로드 (putObject 사용)"""
    file_extension = file.filename.split('.')[-1]
    unique_filename = f"{folder}/{uuid.uuid4().hex}.{file_extension}"

    # 파일 내용을 바이트 스트림으로 읽음
    file_content = file.read()

    # put_object를 사용해 업로드
    s3.put_object(
        Bucket=bucket_name,
        Key=unique_filename,
        Body=file_content,
        ContentType=file.content_type,
        ServerSideEncryption="aws:kms",  # SSE-KMS 암호화
        SSEKMSKeyId=kms_key_id           # KMS 키 ARN
    )

    file_url = f"https://{bucket_name}.s3.amazonaws.com/{unique_filename}"
    return file_url

2) 파일 삭제 함수

S3에서 파일을 삭제하는 함수입니다:

def delete_file_from_s3(file_url):
    """S3에서 파일 삭제"""

    # 파일 경로 추출
    file_key = file_url.split(f"https://{bucket_name}.s3.amazonaws.com/")[-1]

    # S3에서 파일 삭제
    s3.delete_object(Bucket=bucket_name, Key=file_key)

3) Presigned URL 생성 함수

Presigned URL을 생성하여 파일에 대한 임시 접근 권한을 부여할 수 있습니다:

def generate_presigned_url(file_url, expiration=300):
    """Presigned URL 생성"""
    # 파일 경로 추출
    file_key = file_url.split(f"https://{bucket_name}.s3.amazonaws.com/")[-1]

    try:
        url = s3.generate_presigned_url(
            'get_object',
            Params={
                'Bucket': bucket_name,
                'Key': file_key
            },
            ExpiresIn=expiration
        )
        return url
    except Exception as e:
        raise Exception(f"Error generating presigned URL: {str(e)}")

0개의 댓글