Подпись запросов HMAC
Каждый метод /v1/*, включая GET, требует подписи по единой формуле 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 | каждый запрос | Время отправки в миллисекундах Unix (целое число строкой) |
X-TKE-Nonce | каждый запрос | UUID (v4 или v7), уникальный для каждого запроса |
X-TKE-Signature | каждый запрос | HMAC-SHA256 в шестнадцатеричном виде, нижний регистр (формула ниже) |
Idempotency-Key | 5 методы | Строка клиента: одинаковые ключ и тело выполняются ровно один раз; повтор возвращает исходный результат. Область действия — |
Idempotency-Key/v1/ordersPOST/v1/orders/bulkPOST/v1/esims/{id}/cancelPOST/v1/esims/{id}/change-planPOST/v1/esims/{id}/refund-requestsКаноническая формула подписи
Аутентификация HMAC-SHA256 (§4). Передайте 4 заголовка: X-TKE-Key (публичный key_id), X-TKE-Timestamp (мс Unix), X-TKE-Nonce (UUID на запрос), X-TKE-Signature (hex в нижнем регистре). signing_string = method\npath\ntimestamp\nnonce\nbody_hash; body_hash = SHA256(raw_body) hex. Сравнение за постоянное время. path ВКЛЮЧАЕТ строку запроса.
Части соединяются символами перевода строки \n (LF), подпись вычисляется по SHA256(raw_body) вместо исходных байтов тела. Сервер повторно хеширует полученные байты для проверки.
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 lowercaseraw_body = "" → body_hash = SHA256("") = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.Примеры кода подписи HMAC
Скопируйте пример и укажите свои secret и key_id. Отправляйте те же байты, по которым считали хеш; не сериализуйте JSON повторно после подписи.
#!/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"Тестовые векторы сервера
Ниже приведены эталонные векторы, созданные сервером при сборке. Используйте их для проверки своей реализации подписи.
Подпишите точные данные ниже (метод, путь, время, nonce и тело) и проверьте подпись. При несовпадении сравните промежуточную signing_string.
tke_secret_test_0123456789abcdefPOST/v1/orders172068000000011111111-1111-4111-8111-111111111111{"items":[{"package_code":"VN_5GB_30D","quantity":2}]}c197853f7fe46a9f2de1478e565c48ef9369d0152af5117434be8ccfa9391b31POST
/v1/orders
1720680000000
11111111-1111-4111-8111-111111111111
c197853f7fe46a9f2de1478e565c48ef9369d0152af5117434be8ccfa9391b3197147afdebb5d15cf8441278ef524ce15c715ca95962ddb1cb2604a1672fc5d5GET/v1/wallet/balance172068000000022222222-2222-4222-8222-222222222222(пусто)e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855GET
/v1/wallet/balance
1720680000000
22222222-2222-4222-8222-222222222222
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855ab16941884d407924c7b15dea008d6f1d8c0c1be96dca3745344218a99257dbe