Безопасность интеграции
Общие положения
Section titled “Общие положения”Данный раздел описывает основные механизмы защиты, используемые при взаимодействии вашей системы с нашей платформой.
В рамках безопасности применяются два ключевых подхода:
- авторизация всех API-запросов;
- проверка подлинности входящих webhook-уведомлений.
Корректная реализация этих механизмов является обязательной.
Авторизация запросов к API
Section titled “Авторизация запросов к API”Для доступа к API используется API-ключ, который создаётся в личном кабинете мерчанта.
Он служит идентификатором доверенной стороны и подтверждает право на выполнение запросов.
Передача API-ключа
Section titled “Передача API-ключа”API-ключ должен передаваться в каждом запросе в HTTP-заголовке:
X-Secure-Key: your-api-key-valueПример HTTP-запроса
Section titled “Пример HTTP-запроса”POST /example/endpoint HTTP/1.1Host: api.example.comContent-Type: application/jsonX-Secure-Key: your-api-key-value
{ "field1": "value1", "field2": "value2"}Проверка подписи webhook
Section titled “Проверка подписи webhook”Для защиты от поддельных уведомлений все webhook-запросы подписываются.
Подпись передаётся в HTTP-заголовке x-signature.
Проверка подписи позволяет убедиться, что:
- запрос отправлен нашей системой;
- содержимое запроса не было изменено.
Порядок проверки подписи
Section titled “Порядок проверки подписи”- Получите тело запроса в исходном виде (raw JSON).
- Извлеките значение заголовка
x-signature. - Сформируйте подпись на основе тела запроса и API-ключа.
- Сравните вычисленную подпись с полученной.
Алгоритм формирования подписи
Section titled “Алгоритм формирования подписи”Для генерации подписи используется алгоритм HMAC-SHA256.
В расчёте участвуют:
- тело запроса (без каких-либо изменений);
- API-ключ, используемый как секрет.
Результат вычисления кодируется в hex-формате.
Примеры реализации
Section titled “Примеры реализации”JavaScript (Node.js)
Section titled “JavaScript (Node.js)”const crypto = require('crypto');
function verifySignature(apiKey, body, signature) { const expected = crypto .createHmac('sha256', apiKey) .update(body) .digest('hex');
return crypto.timingSafeEqual( Buffer.from(signature, 'hex'), Buffer.from(expected, 'hex') );}TypeScript
Section titled “TypeScript”import * as crypto from 'crypto';
export function verifySignature( apiKey: string, body: string, signature: string): boolean { const expected = crypto .createHmac('sha256', apiKey) .update(body) .digest('hex');
return crypto.timingSafeEqual( Buffer.from(signature, 'hex'), Buffer.from(expected, 'hex') );}Python
Section titled “Python”import hmacimport hashlib
def verify_signature(api_key: str, body: str, signature: str) -> bool: expected = hmac.new( api_key.encode(), body.encode(), hashlib.sha256 ).hexdigest()
return hmac.compare_digest(expected, signature)function verifySignature(string $apiKey, string $body, string $signature): bool { $expected = hash_hmac('sha256', $body, $apiKey); return hash_equals($expected, $signature);}import javax.crypto.Mac;import javax.crypto.spec.SecretKeySpec;import java.nio.charset.StandardCharsets;import java.security.MessageDigest;
public class WebhookSignatureValidator {
public static boolean verify( String apiKey, String body, String signature ) throws Exception {
Mac mac = Mac.getInstance("HmacSHA256"); mac.init(new SecretKeySpec(apiKey.getBytes(StandardCharsets.UTF_8), "HmacSHA256")); byte[] hash = mac.doFinal(body.getBytes(StandardCharsets.UTF_8));
return MessageDigest.isEqual( toHex(hash).getBytes(), signature.getBytes() ); }
private static String toHex(byte[] data) { StringBuilder sb = new StringBuilder(); for (byte b : data) { sb.append(String.format("%02x", b)); } return sb.toString(); }}func verifySignature(apiKey, body, signature string) bool { mac := hmac.New(sha256.New, []byte(apiKey)) mac.Write([]byte(body)) expected := hex.EncodeToString(mac.Sum(nil)) return hmac.Equal([]byte(signature), []byte(expected))}Обработка ошибок
Section titled “Обработка ошибок”Если подпись не прошла проверку, webhook-запрос должен быть отклонён с ответом:
HTTP 401 UnauthorizedЗапросы с некорректной подписью не должны обрабатываться бизнес-логикой.
Примечания
Section titled “Примечания”- Подпись всегда проверяется до обработки данных
- Тело запроса должно использоваться в неизменённом виде
- Любое расхождение подписи считается критической ошибкой
Данные меры обязательны для обеспечения безопасной и стабильной работы интеграции.