최신 업데이트: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 연산을 수행해 최종 서명을 계산합니다.
서명 프로세스의 시작은 요청 정보를 표준(정규) 형식으로 나열한 문자열을 만드는 것입니다. 이를 통해 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 요청처럼 본문이 없을 때는 빈 문자열의 해시값을 사용합니다. |
서명 문자열(String to Sign)은 Task 1: 서명용 정규 요청 생성에서 만든 정규 요청과 요청의 메타 정보를 포함합니다. 이 문자열과 이후 생성할 서명 키를 Task 3: 서명 계산의 입력값으로 사용합니다.
서명 문자열은 다음의 문자열을 이어붙여 작성합니다:
"WOS-HMAC-SHA256" + "\n" +
TimeStamp + "\n" +
<Scope> + "\n" +
Hex(SHA256Hash(<Canonical Request>))
설명:
WOS-HMAC-SHA256은 고정값으로, 사용 중인 해시 알고리즘(HMAC-SHA256)을 명시합니다;TimeStamp는 현재 시간을 ISO8601 형식(yyyyMMdd’T’HHmmss’Z’)으로 기록합니다. 이 값은 이전 단계(예: x-wos-date)에 사용한 값과 동일해야 합니다.Scope는 서명을 특정 날짜 및 서비스 리전에 한정하기 위해 사용합니다. 예:20170606/cn-east-1/wos/wos_request에서20170606은 서명의 유효 시작일,cn-east-1은 OS 리전 이름입니다.Hex(SHA256Hash(<Canonical Request>))는 Task 1: 서명용 정규 요청 생성에서 만든 CanonicalRequest의 SHA256 해시입니다. 문자열 끝에 줄바꿈은 추가하지 않습니다.
서명 계산 전, 비밀 액세스 키로부터 서명 키(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 함수의 매개변수 순서에 유의하세요. 예시에서는 키가 첫 번째, 데이터(메시지)가 두 번째 매개변수이나 사용 환경에 따라 순서가 다를 수 있습니다.