다큐멘트 센터 Object Storage API Examples: Signature Calculations

Examples: Signature Calculations

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

인증이 필요한 요청의 경우, SDK를 사용하지 않는다면 요청에 인증 정보를 제공하는 서명(Signature)을 직접 코드로 계산해야 합니다. 서명 계산은 복잡할 수 있으므로, 가능하면 SDKs 사용을 권장합니다.
이 섹션에서는 서명 계산 방식을 예시와 함께 설명합니다. 예를 들어, API GetBucket을 호출하여 test-authentication 버킷에서 "OS"로 시작하는 파일 목록을 조회한다고 가정합니다. 요청 예시는 다음과 같습니다:

예시 요청

GET /?prefix=OS HTTP/1.1
Host: test-authentication.s3-cn-north-1.wcsapi.com
x-wos-date:20201103T104419Z
Authorization: <Authorization>

인증 헤더와 함께 GET 요청 보내기(Python)

import sys, os, base64, datetime, hashlib, hmac 
import requests

# ************* 요청 값 정의 *************
# 아래 코드는 인증 정보를 헤더에 포함시키는 방법을 보여줍니다.
# 예시로 GetBucket API를 사용합니다.
# GET /?prefix=OS
# Host: test-authentication.s3-cn-north-1.wcsapi.com
service = 'wos'
host = 'test-authentication.s3-cn-north-1.wcsapi.com'  
region = 'cn-north-1'
endpoint = 'http://test-authentication.s3-cn-north-1.wcsapi.com'
request_parameters = 'prefix=OS'

# Key 파생 함수
def sign(key, msg):
    return hmac.new(key, msg.encode('utf-8'), hashlib.sha256).digest()

# SigningKey 파생 함수
def getSignatureKey(key, dateStamp, regionName, serviceName):
    kDate = sign(('WOS' + key).encode('utf-8'), dateStamp)
    kRegion = sign(kDate, regionName)
    kService = sign(kRegion, serviceName)
    kSigning = sign(kService, 'wos_request')
    return kSigning

# Access Key 및 Access Key Secret. 환경 변수나 설정 파일에서 읽을 수도 있습니다.
access_key = 'LqswcPGFYA06V0fQ2HtgVRR3Wi5fzpR******'
secret_key = 'B2UZV6uwULVnosYQxORTYSdbTTAJVptWvDoV0fLENgA3ERPc8UxYfvTigS******'

if access_key is None or secret_key is None:
    print('No access key is available.')
    sys.exit()

# 헤더 및 Credential String 생성을 위한 날짜
t = datetime.datetime.utcnow()
wosdate = t.strftime('%Y%m%dT%H%M%SZ')

print('wosdate is: ' + wosdate)
datestamp = t.strftime('%Y%m%d') # Credential 범위 지정 시 시간 제외

# ************* 1단계: 정규 요청 생성 *************
# 1. HTTP 메서드 정의(GET, POST 등)
method = 'GET'
# 2. 정규 URI 생성 - GetBucket은 경로가 없으므로 '/'
canonical_uri = '/' 

# 3. 정규 쿼리 문자열 생성. 이 예제(GET 요청)에서는 파라미터가 쿼리 문자열에 포함됩니다.
# 파라미터 값은 URL 인코딩(공백=%20)되어야 하며, 이름 기준으로 정렬합니다.
# 이 예제에서는 'prefix=OS'만 존재합니다.
canonical_querystring = request_parameters

# 4. 정규 헤더 및 서명 헤더 생성. 헤더 이름은 소문자로 정렬해야 하며, 줄바꿈으로 구분합니다.
canonical_headers = 'host:' + host + '\n' + 'x-wos-date:' + wosdate + '\n'

# 5. 서명에 포함될 헤더 리스트. 정렬 후 세미콜론(;)으로 구분합니다.
# "Host"와 "x-wos-date"는 반드시 포함해야 합니다.
signed_headers = 'host;x-wos-date'

# 6. 페이로드 해시 생성(GET 요청은 본문이 없으므로 빈 문자열 해시 사용)
payload_hash = hashlib.sha256(('').encode('utf-8')).hexdigest()

# 7. 요소를 결합하여 정규 요청 문자열 생성
canonical_request = method + '\n' + canonical_uri + '\n' + canonical_querystring + '\n' + canonical_headers + '\n' + signed_headers + '\n' + payload_hash

# ************* 2단계: 서명용 문자열 생성 *************
# 알고리즘 설정
algorithm = 'WOS-HMAC-SHA256'
credential_scope = datestamp + '/' + region + '/' + service + '/' + 'wos_request'
string_to_sign = algorithm + '\n' +  wosdate + '\n' +  credential_scope + '\n' +  hashlib.sha256(canonical_request.encode('utf-8')).hexdigest()

# ************* 3단계: 서명 계산 *************
# 위 함수로 signing key 생성
signing_key = getSignatureKey(secret_key, datestamp, region, service)

# signing_key로 string_to_sign에 서명
signature = hmac.new(signing_key, (string_to_sign).encode('utf-8'), hashlib.sha256).hexdigest()
print(signature)

# ************* 4단계: 요청에 서명 정보 추가 *************
# Authorization 헤더 생성 후 요청 헤더에 추가
authorization_header = algorithm + ' ' + 'Credential=' + access_key + '/' + credential_scope + ', ' +  'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + signature
headers = {'x-wos-date':wosdate, 'Authorization':authorization_header}

# ************* 요청 전송 *************
request_url = endpoint + '?' + canonical_querystring

print('\nBEGIN REQUEST++++++++++++++++++++++++++++++++++++')
print('Request URL = ' + request_url)
r = requests.get(request_url, headers=headers)

print('\nRESPONSE++++++++++++++++++++++++++++++++++++')
print('Response code: %d\n' % r.status_code)
print(r.text)
이 문서의 내용이 도움이 되었습니까?
아니오
정상적으로 제출되었습니다.피드백을 주셔서 감사합니다.앞으로도 개선을 위해 노력하겠습니다.