AWS S3 파일 업로드 SignatureDoesNotMatch 에러 해결

지쥬·2025년 11월 5일

AWS

목록 보기
3/4
post-thumbnail

Spring Boot에서 AWS S3에 파일 업로드 시 403 에러 발생:
The request signature we calculated does not match the signature you provided.
Check your key and signing method. (Service: S3, Status Code: 403)

시도한 해결 방법들

1. YAML 설정에 따옴표 추가

  • Secret Key에 특수문자(+, /)가 포함되어 YAML 파싱 문제 의심
  • secret-key: "abcd/efghijklmnop" 형태로 수정

2. AWS SDK v1 → v2 마이그레이션

  • 블로그에서 SDK v1.12.460+ 버전에서 bucket/key 혼용 시 서명 문제 발생한다는 정보 확인
  • build.gradle에서 SDK v2로 변경
    implementation platform('software.amazon.awssdk:bom:2.20.26')
    implementation 'software.amazon.awssdk:s3'

3. 새로운 IAM 사용자 및 Access Key 생성

  • 기존 Access Key 손상 의심
  • s3_user 생성 후 AmazonS3FullAccess 권한 부여
  • 새 Access Key 발급

4. application.yaml 중복 설정 제거

  • application.yaml에서 환경 변수로 AWS 설정을 덮어쓰고 있던 문제 발견

핵심 원인

AWS SDK v2의 서명 계산 과정에서:
1. HTTP 헤더에 metadata가 포함됨 (x-amz-meta-original-filename)
2. 한국어가 URL 인코딩되면서 서명 계산에 사용되는 값이 달라짐
3. 서버에서 검증 시 서명 불일치 → 403 에러

AWS CLI로 같은 자격 증명 테스트:
AWS_ACCESS_KEY_ID="AKIA..." \
AWS_SECRET_ACCESS_KEY="zgTF..." \
aws s3 cp test.txt s3://test-buket/test.txt --region ap-northeast-2
→ 성공! (자격 증명은 문제 없음을 확인)

최종 해결 방법

metadata에 한국어 파일명 포함으로 인한 서명 문제!

❌ 문제 코드

PutObjectRequest putObjectRequest = PutObjectRequest.builder()
    .bucket(bucketName)
    .key(s3Key)
    .contentType(file.getContentType())
    .metadata(java.util.Map.of("original-filename", originalFilename))  // 한국어!
    .build();

✅ 해결: metadata 제거

PutObjectRequest putObjectRequest = PutObjectRequest.builder()
    .bucket(bucketName)
    .key(s3Key)
    .contentType(file.getContentType())
    .build();

참고 사항

  1. AWS SDK v2 추천: v1은 더 이상 유지보수되지 않음
  2. IAM 사용자 분리: S3 전용 IAM 사용자를 별도로 생성하는 것이 보안상 좋음
  3. metadata 사용 시 주의: 한글/특수문자 포함 시 인코딩 문제 발생 가능

0개의 댓글