다큐멘트 센터 Object Storage API Signature Calculation

Signature Calculation

최신 업데이트:2025-08-18 15:49:24

HTTP 요청에서 Authorization 헤더를 포함해 서명 정보를 전달하고 요청자가 인증되었음을 나타낼 수 있습니다.

형식 설명

서명 정보는 HTTP 메시지의 authorization 헤더에 담깁니다. Authorization의 형식은 다음과 같습니다:

Authorization:WOS-HMAC-SHA256
Credential=<AccessKeyId >/<Date>/<Region>/<Service>/wos_request,
SignedHeaders=<SignedHeader>;<SignedHeader>;<SignedHeader>,
Signature=<Signature>

참고: 예시의 줄바꿈은 가독성을 위한 것으로, 실제 사용 시에는 한 줄로 작성해야 합니다.

Authorization 매개변수 설명

매개변수 설명
WOS-HMAC-SHA256 고정값. 서명 계산에 사용되는 알고리즘입니다. 서명 알고리즘은 HMAC-SHA256입니다.
Credential 액세스 키 ID와 서명의 계산에 사용된 날짜, 리전, 서비스 등 범위 정보가 포함됩니다.
이 문자열은 다음 형태입니다:
<AccessKeyId>/<Date>/<Region>/<Service>/wos_request
구성 요소:
<AccessKeyId>: 비밀키.
<Date>: YYYYMMDD 형식의 날짜.
<Region>: 리전 이름(예: cn-south-1).
<Service>: 서비스 타입. 고정값 ‘wos’.
SignedHeaders Signature 계산 시 사용된 요청 헤더 목록입니다. 헤더 이름만 소문자로 세미콜론(;)으로 구분해 나열합니다. 예시:
host;range;x-wos-date
Signature 256비트 서명을 64자의 소문자 16진수로 표현합니다. 예시:
0243fe336dc075f95add64c5fe980ae6fd0446b243e0f301e4ad75d32d96dc6a

서명 단계

서명 계산은 일반적으로 다음 단계를 통해 이루어집니다:
1. 정규 요청(Canonical Request) 생성: 요청의 내용(호스트, 액션, 헤더 등)을 표준(정규) 형식으로 정렬합니다. 이 정규화된 요청은 서명을 위한 문자열 생성에 입력값으로 사용됩니다.
2. 서명 문자열(String To Sign) 생성: 정규 요청과 알고리즘, 요청 날짜, Credential 범위, 정규 요청의 해시 등 추가 정보를 포함해 서명 문자열을 만듭니다.
3. 서명(Signature) 계산: 먼저 요청 날짜, 리전, 서비스 정보를 비밀 액세스 키와 함께 연속적으로 HMAC 연산을 수행해 서명 키(signing key)를 도출합니다.

서명 키를 구한 후, 이 키를 이용해 서명 문자열에 HMAC 연산을 수행해 최종 서명을 계산합니다.

1단계: 정규 요청(Canonical Request) 생성

서명 프로세스의 시작은 요청 정보를 표준(정규) 형식으로 나열한 문자열을 만드는 것입니다. 이를 통해 OS에서 동일한 방식으로 서명을 재현하여, 요청이 무결하게 전달되었는지 검증할 수 있습니다.

정규 요청을 작성할 때는 다음 형식을 따릅니다:

<HTTPMethod> + "\n" +
<CanonicalURI> + "\n" +
<CanonicalQueryString> + "\n" +
<CanonicalHeaders> + "\n" +
<SignedHeaders> + "\n" +
<HashedPayload>

각 항목 설명은 다음과 같습니다:

항목 설명
HTTPMethod HTTP 메서드 중 하나를 지정합니다. 예: GET, PUT, HEAD, DELETE 등
CanonicalURI URI의 절대 경로(도메인 뒤의 "/"부터 ‘?’ 또는 문자열 끝까지)를 URI 인코딩하여 사용합니다.
예: http://Bucket.Endpoint/myphoto.jpg의 절대 경로는 /myphoto.jpg입니다.
CanonicalQueryString URI 인코딩된 쿼리 문자열 파라미터를 명시합니다.
1. 예시 요청 URL: http://Bucket.Endpoint?prefix=somePrefix&marker=someMarker&max-keys=20에서 CanonicalQueryString은
UriEncode("marker") + "=" + UriEncode("someMarker") + "&" + UriEncode("max-keys") + "=" + UriEncode("20") + "&" + UriEncode("prefix") + "=" + UriEncode("somePrefix")
2. 하위 리소스 요청 시, 파라미터 값은 빈 문자열 ““이 됩니다.
예: http://Bucket.Endpoint?acl일 때
CanonicalQueryString은 UriEncode("acl") + "=" + ""
3. '?'가 없는 경우, 쿼리 문자열이 없으므로 CanonicalQueryString은 빈 문자열(””)로 설정해야 하며, 이 때도 "\n"을 포함해야 합니다.
CanonicalHeaders 요청 헤더와 그 값을 나열한 목록입니다. 각 헤더 이름과 값 쌍은 줄바꿈("\n")으로 구분합니다. 헤더 이름은 소문자로 변환해서 알파벳 순으로 정렬해야 합니다.
CanonicalHeaders에는 반드시 다음이 포함되어야 합니다:
1. HTTP host 헤더
2. Content-Type 헤더가 요청에 있다면 반드시 포함
3. 요청에 포함할 모든 x-wos-* 헤더
예시:
host:bucket.endPoint,x-wos-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b785,x-wos-date:20170524T000000Z
참고:
1. x-wos-content-sha256 헤더는 반드시 서명 계산에 포함되어야 하며, 이는 본문(payload)의 해시값입니다. 본문이 없다면 빈 문자열의 해시값을 사용합니다.
2. 데이터 변조를 막기 위해 모든 요청 헤더를 서명에 포함하는 것을 권장합니다.
SignedHeaders 알파벳 순으로 정렬된 소문자 요청 헤더 이름을 세미콜론(;)으로 구분해 나열합니다. 이 목록은 CanonicalHeaders와 동일한 헤더로 구성해야 합니다.
예시에서 SignedHeaders는 다음과 같습니다:
host;x-wos-content-sha256;x-wos-date
HashedPayload 요청 본문의 SHA256 해시값을 16진수로 나타냅니다. 본문이 없다면 빈 문자열로 해시를 구하는데, 이때의 해시값은 다음과 같습니다:
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
예를 들어 PUT 요청으로 객체를 업로드할 때는 본문 데이터를 사용하며, GET 요청처럼 본문이 없을 때는 빈 문자열의 해시값을 사용합니다.

2단계: 서명 문자열(String To Sign) 생성

서명 문자열(String to Sign)은 Task 1: 서명용 정규 요청 생성에서 만든 정규 요청과 요청의 메타 정보를 포함합니다. 이 문자열과 이후 생성할 서명 키를 Task 3: 서명 계산의 입력값으로 사용합니다.

서명 문자열은 다음의 문자열을 이어붙여 작성합니다:

"WOS-HMAC-SHA256" + "\n" +
TimeStamp + "\n" +
<Scope> + "\n" +
Hex(SHA256Hash(<Canonical Request>))

설명:

  1. WOS-HMAC-SHA256은 고정값으로, 사용 중인 해시 알고리즘(HMAC-SHA256)을 명시합니다;
  2. TimeStamp는 현재 시간을 ISO8601 형식(yyyyMMdd’T’HHmmss’Z’)으로 기록합니다. 이 값은 이전 단계(예: x-wos-date)에 사용한 값과 동일해야 합니다.
  3. Scope는 서명을 특정 날짜 및 서비스 리전에 한정하기 위해 사용합니다. 예: 20170606/cn-east-1/wos/wos_request에서 20170606은 서명의 유효 시작일, cn-east-1은 OS 리전 이름입니다.
  4. Hex(SHA256Hash(<Canonical Request>))Task 1: 서명용 정규 요청 생성에서 만든 CanonicalRequest의 SHA256 해시입니다. 문자열 끝에 줄바꿈은 추가하지 않습니다.

3단계: 서명(Signature) 계산

서명 계산 전, 비밀 액세스 키로부터 서명 키(Signing Key)를 도출해야 합니다. 서명 키는 날짜, 서비스, 리전을 범위로 하여 보안성을 더 높입니다. 이후, 서명 키와 Task 2: 서명 문자열 생성에서 만든 서명 문자열을 입력으로 하여 최종 서명을 계산합니다.

1. 서명 키 도출
서명 키는 여러 단계의 연속된 HMAC 연산을 통해 구합니다. 각 단계의 결과를 다음 단계의 입력값으로 사용하며, 마지막 단계의 결과가 최종 서명 키입니다:

1. DateKey = HMAC-SHA256("WOS"+"<SecretKey>", "<Date>")
2. DateRegionKey = HMAC-SHA256(<DateKey>, "<Region>")
3. DateRegionServiceKey = HMAC-SHA256(<DateRegionKey>, "wos")
4. SigningKey = HMAC-SHA256(<DateRegionServiceKey>, "wos_request")

HMAC-SHA256(key, data)는 HMAC-SHA256 함수를 의미하며, 결과는 바이너리 형식입니다. <SecretKey>는 비밀 액세스 키이고, <Region>은 버킷의 리전 이름입니다.

입력 예시

SigningKey = HMAC-SHA256(HMAC-SHA256(HMAC-SHA256(HMAC-SHA256("WOS" + "EfxET06Dvb2cahG8OBtZH9WRqkB3EXAMPLEKEY","20201103"),"cn-south-1"),"wos"),"wos_request")

이 예시는 2020년 11월 3일에 cn-south-1 리전에 OS 요청을 보낸 경우를 나타냅니다.

2. 서명 계산
최종 서명 값은 서명 키를 사용하여 서명 문자열에 HMAC-SHA256 해시를 수행한 결과입니다. 계산 방법은 다음과 같습니다:

signature = HMAC-SHA256(SigningKey, StringToSign)

참고: 사용하는 프로그래밍 언어에서 HMAC 함수의 매개변수 순서에 유의하세요. 예시에서는 키가 첫 번째, 데이터(메시지)가 두 번째 매개변수이나 사용 환경에 따라 순서가 다를 수 있습니다.

이 문서의 내용이 도움이 되었습니까?
아니오
정상적으로 제출되었습니다.피드백을 주셔서 감사합니다.앞으로도 개선을 위해 노력하겠습니다.