Tổng Kho eSIM
인증

HMAC 요청 서명

GET을 포함한 모든 /v1/* 요청에는 HMAC-SHA256 서명이 필요합니다. 서버는 타이밍 공격 방지를 위해 상수 시간 비교를 사용합니다.

바로 실행할 파일이 필요하신가요? 다음을 확인하세요: 직접 연동 페이지 동일한 서명 공식의 예시 파일, Postman, .http를 다운로드할 수 있습니다.

연동 가이드 보기

필수 헤더

처음 4개 헤더는 모든 요청에 필수이며 openapi.json 보안 스키마에서 가져옵니다.

헤더유형의미
X-TKE-Key모든 요청공개 key_id (tke_live_… / tke_test_… / tke_member_live_… / tke_member_test_…)
X-TKE-Timestamp모든 요청유닉스 시간 밀리초 (정수 문자열)
X-TKE-Nonce모든 요청요청별 고유 UUID v4 또는 v7
X-TKE-Signature모든 요청소문자 16진수 HMAC-SHA256
Idempotency-Key5 엔드포인트

클라이언트 생성 문자열입니다. 같은 키와 본문은 한 번만 실행되며 재시도는 원래 결과를 반환합니다. api_key_id 단위(§11)이므로 다른 키는 별개 명령입니다.

필수 엔드포인트: Idempotency-Key
POST/v1/ordersPOST/v1/orders/bulkPOST/v1/esims/{id}/cancelPOST/v1/esims/{id}/change-planPOST/v1/esims/{id}/refund-requests

서명 정규화 공식

HMAC-SHA256 인증(§4)입니다. X-TKE-Key(공개 key_id), X-TKE-Timestamp(epoch 밀리초), X-TKE-Nonce(요청별 UUID), X-TKE-Signature(소문자 16진수) 네 헤더를 전송합니다. signing_string = method path timestamp nonce body_hash이며 body_hash = SHA256(raw_body)의 16진수입니다. 상수 시간 비교를 사용하며 path에는 쿼리 문자열이 포함됩니다.

각 부분은 줄바꿈으로 연결합니다 \n (LF), 서명 대상: SHA256(raw_body) 본문 자체 대신 사용합니다. 서버가 수신한 정확한 바이트를 다시 해시하여 검증합니다.

text
signing_string = method + "\n"
               + path + "\n"        # 쿼리 포함, 스킴/호스트 제외
               + timestamp + "\n"   # = header X-TKE-Timestamp (epoch ms)
               + nonce + "\n"       # = header X-TKE-Nonce
               + body_hash          # SHA256(raw_body) hex lowercase

signature = HMAC_SHA256(secret, signing_string)   → hex lowercase
GET, DELETE 또는 빈 본문의 경우 raw_body = "" → body_hash = SHA256("") = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.

HMAC 서명 예제

secret과 key_id를 바꾸세요. 해시한 바이트 그대로 보내고 서명 후 다시 직렬화하지 마세요.

bash
#!/usr/bin/env bash
# Yeu cau: openssl. Ky POST /v1/orders.
KEY_ID="tke_test_ab12cd34..."
SECRET="tke_secret_test_0123456789abcdef"
METHOD="POST"
PATH_Q="/v1/orders"
BODY='{"items":[{"package_code":"THAY-BANG-MA-GOI-CUA-BAN","quantity":2}]}'
TS="$(date +%s000)"                 # epoch milliseconds
NONCE="$(uuidgen)"

BODY_HASH="$(printf '%s' "$BODY" | openssl dgst -sha256 -hex | awk '{print $NF}')"
SIGNING="$METHOD"$'
'"$PATH_Q"$'
'"$TS"$'
'"$NONCE"$'
'"$BODY_HASH"
SIG="$(printf '%s' "$SIGNING" | openssl dgst -sha256 -hmac "$SECRET" -hex | awk '{print $NF}')"

curl -sS "https://api.tongkhoesim.com$PATH_Q"   -H "X-TKE-Key: $KEY_ID"   -H "X-TKE-Timestamp: $TS"   -H "X-TKE-Nonce: $NONCE"   -H "X-TKE-Signature: $SIG"   -H "Idempotency-Key: $(uuidgen)"   -H "Content-Type: application/json"   --data-raw "$BODY"

백엔드 테스트 벡터

백엔드가 생성한 벡터로 서명 구현을 검증하세요.

아래 입력 그대로 서명 후 비교하세요. 다르면 signing_string으로 원인을 확인하세요.

예시 비밀 키: tke_secret_test_0123456789abcdef
POST /v1/orders
methodPOST
path/v1/orders
timestamp1720680000000
nonce11111111-1111-4111-8111-111111111111
raw_body{"items":[{"package_code":"VN_5GB_30D","quantity":2}]}
body_hashc197853f7fe46a9f2de1478e565c48ef9369d0152af5117434be8ccfa9391b31
signing_string
POST
/v1/orders
1720680000000
11111111-1111-4111-8111-111111111111
c197853f7fe46a9f2de1478e565c48ef9369d0152af5117434be8ccfa9391b31
signature (예상 결과)
97147afdebb5d15cf8441278ef524ce15c715ca95962ddb1cb2604a1672fc5d5
GET /v1/wallet/balance
methodGET
path/v1/wallet/balance
timestamp1720680000000
nonce22222222-2222-4222-8222-222222222222
raw_body(비어 있음)
body_hashe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
signing_string
GET
/v1/wallet/balance
1720680000000
22222222-2222-4222-8222-222222222222
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
signature (예상 결과)
ab16941884d407924c7b15dea008d6f1d8c0c1be96dca3745344218a99257dbe