API использует JSON формат для обмена данными. Все запросы должны содержать обязательные заголовки для аутентификации и подписи.
Базовый URL: https://your-api-domain.com (уточните у администратора)
Формат данных: JSON
Кодировка: UTF-8
Все запросы должны содержать заголовок X-Key-ID. Заголовок X-Signature требуется только для эндпоинта /pay (если требуется для ключа).
| Заголовок | Описание | Обязательность |
|---|---|---|
X-Key-ID |
Идентификатор ключа (выдается администратором) | Обязательно для всех эндпоинтов |
X-Signature |
Подпись тела запроса в формате base64 | Обязательно только для эндпоинта /pay |
Пример заголовков для /check:
X-Key-ID: your-key-id-12345
Пример заголовков для /pay:
X-Key-ID: your-key-id-12345
X-Signature: base64-encoded-signature
Важно: Подпись X-Signature требуется только для эндпоинта /pay. Для эндпоинта /check подпись не требуется.
Подпись X-Signature обеспечивает целостность и аутентичность данных запроса. Процесс формирования подписи состоит из следующих шагов:
Пример тела запроса:
{"order_id":"550e8400-e29b-41d4-a716-446655440000","amount":10000,"external_id":"ext-12345"}
Вычислите SHA-256 хеш от байтового представления тела запроса:
hash = SHA256(body_bytes)
Подпишите хеш с помощью приватного RSA ключа, соответствующего X-Key-ID. Используется алгоритм RSA PKCS#1 v1.5:
signature_bytes = RSA_Sign(hash, private_key, PKCS1v15)
Параметры:
Закодируйте полученную подпись в base64:
X-Signature = base64_encode(signature_bytes)
Поддерживаются два варианта кодирования:
/pay. Сервер проверяет подпись используя публичный ключ из сертификата, связанного с X-Key-ID. Убедитесь, что используете правильный приватный ключ, соответствующий сертификату./pay. При ошибке проверки подписи сервер возвращает MD5 хеш публичного ключа в сообщении об ошибке для отладки. Для проверки соответствия ключа и сертификата см. раздел Проверка соответствия ключа и сертификата.Эндпоинт: POST /check
Описание: Проверяет существование заказа и возвращает его данные (идентификаторы, сумму, телефон, описание, статус). Поддерживает поиск по order_id (UUID) или hash_id (короткий 10-значный идентификатор).
Заголовки:
X-Key-ID: your-key-id
Примечание: Для эндпоинта /check подпись не требуется, достаточно указать только X-Key-ID.
Тело запроса:
{
"order_id": "550e8400-e29b-41d4-a716-446655440000"
}
или
{
"hash_id": "1234567890"
}
или
{
"order_id": "550e8400-e29b-41d4-a716-446655440000",
"hash_id": "1234567890"
}
Параметры:
order_id (string, опционально) - UUID идентификатор заказа. Если указан, поиск выполняется по order_id без ограничений по времениhash_id (string, опционально) - короткий идентификатор заказа (10 цифр)Примечание: Должен быть указан хотя бы один из параметров (order_id или hash_id). Если указаны оба параметра, приоритет у order_id (поиск выполняется по order_id без ограничений по времени).
{
"success": true,
"order_id": "550e8400-e29b-41d4-a716-446655440000",
"hash_id": "1234567890",
"amount": 10000,
"phone": "+79991234567",
"description": "Оплата заказа",
"status": "new",
"expired_at": "2024-12-31T23:59:59Z",
"user_data": {"custom_field":"value"}
}
Поля ответа:
success (boolean) - всегда true при успешном ответеorder_id (string) - UUID идентификатор заказаhash_id (string) - короткий идентификатор заказа (10 цифр)amount (integer) - сумма заказа в минимальных единицах валюты (копейки для RUB)phone (string) - номер телефонаdescription (string) - описание заказаstatus (string) - статус заказа (см. раздел Статусы заказов)expired_at (string, опционально) - дата и время истечения срока действия заказа в формате ISO 8601 (если заказ не просрочен)user_data (object или string, опционально) - произвольные данные заказа. Валидный JSON выводится как объект/массив без экранирования, обычная строка — как JSON-строка (см. раздел User Data)error (string, опционально) - присутствует, если статус заказа отличается от newЕсли заказ не найден:
{
"success": false,
"error": "validation error: order not found"
}
Если данные недоступны, системная ошибка:
{
"success": false,
"error": "system error"
}
# Поиск по order_id
curl -X POST "https://api.example.com/check" \
-H "X-Key-ID: your-key-id" \
-H "Content-Type: application/json" \
-d '{"order_id":"550e8400-e29b-41d4-a716-446655440000"}'
# Поиск по hash_id
curl -X POST "https://api.example.com/check" \
-H "X-Key-ID: your-key-id" \
-H "Content-Type: application/json" \
-d '{"hash_id":"1234567890"}'
# Поиск по обоим параметрам (приоритет у order_id)
curl -X POST "https://api.example.com/check" \
-H "X-Key-ID: your-key-id" \
-H "Content-Type: application/json" \
-d '{"order_id":"550e8400-e29b-41d4-a716-446655440000","hash_id":"1234567890"}'
Эндпоинт: POST /pay
Описание: Инициирует и завершает транзакцию оплаты заказа.
Важно: Параметр external_id является обязательным и должен быть уникальным для каждой попытки оплаты.
Заголовки:
X-Key-ID: your-key-id
X-Signature: base64-encoded-signature
Примечание: Для эндпоинта /pay подпись X-Signature обязательна. Без подписи запрос будет отклонен.
Тело запроса:
{
"order_id": "550e8400-e29b-41d4-a716-446655440000",
"amount": 10000,
"external_id": "ext-12345"
}
С опциональным узлом account:
{
"order_id": "550e8400-e29b-41d4-a716-446655440000",
"amount": 10000,
"external_id": "ext-12345",
"account": {
"resident": 1,
"personal_account_number": 12345678901
}
}
Параметры:
order_id (string, обязательно) - UUID идентификатор заказаamount (integer, обязательно) - сумма платежа в минимальных единицах валюты. Должна быть больше 0external_id (string, обязательно) - внешний идентификатор транзакции (уникальный для каждой попытки оплаты)account (object, опционально) - данные счёта для расчёта 20-значного номера счёта. При указании вычисляется номер счёта по правилам банка и сохраняется в заказ. Поля узла:
resident (number или string) - признак резидентства: 1 — резидент, 0 — нерезидентpersonal_account_number (number или string) - лицевой номер счёта (11 цифр){
"success": true,
"order_id": "550e8400-e29b-41d4-a716-446655440000",
"transaction_id": "txn-12345",
"status": "completed"
}
Поля ответа:
success (boolean) - всегда true при успешном ответеorder_id (string) - UUID идентификатор заказаtransaction_id (string) - идентификатор созданной транзакцииstatus (string) - финальный статус заказа после обработки транзакции (см. раздел Статусы заказов)Если транзакция была создана, но есть ошибка валидации:
{
"success": true,
"order_id": "550e8400-e29b-41d4-a716-446655440000",
"transaction_id": "txn-12345",
"status": "declined",
"error": "validation error: transaction amount not match order amount: 10000, 5000"
}
Если транзакция не была создана:
{
"success": false,
"error": "system error"
}
curl -X POST "https://api.example.com/pay" \
-H "X-Key-ID: your-key-id" \
-H "X-Signature: base64-encoded-signature" \
-H "Content-Type: application/json" \
-d '{
"order_id": "550e8400-e29b-41d4-a716-446655440000",
"amount": 10000,
"external_id": "ext-12345"
}'
С узлом account:
curl -X POST "https://api.example.com/pay" \
-H "X-Key-ID: your-key-id" \
-H "X-Signature: base64-encoded-signature" \
-H "Content-Type: application/json" \
-d '{
"order_id": "550e8400-e29b-41d4-a716-446655440000",
"amount": 10000,
"external_id": "ext-12345",
"account": {
"resident": 1,
"personal_account_number": 12345678901
}
}'
API возвращает статус заказа в поле status ответов. Доступны следующие статусы:
| Статус | Значение | Финальный | Описание |
|---|---|---|---|
new |
Новый заказ | Нет | Заказ создан и готов к оплате. В этом статусе заказ может быть оплачен через эндпоинт /pay |
in_progress |
Заказ в процессе | Нет | Заказ находится в процессе оплаты. Транзакция создана, но еще не завершена |
completed |
Заказ завершен | Да | Заказ успешно оплачен. Транзакция завершена без ошибок |
declined |
Заказ отклонен | Да | Заказ отклонен из-за ошибки при оплате. Транзакция завершена с ошибкой |
expired |
Заказ просрочен | Нет | Срок действия заказа истек (TTL). Заказ автоматически переходит в этот статус при истечении срока действия |
1. Создание заказа
└─> status: "new"
2. Начало оплаты (POST /pay)
├─> Заказ: status: "in_progress"
3. Завершение оплаты
├─> Если успешно (error отсутствует):
│ ├─> Заказ: status: "completed"
│
└─> Если ошибка (error указан):
├─> Заказ: status: "declined"
4. Истечение срока действия (TTL)
└─> Заказ: status: "expired" (автоматически)
5. Оплата просроченного заказа (POST /pay для заказа со статусом expired)
├─> Если успешно (error отсутствует):
│ ├─> Заказ: status: "completed"
│
└─> Если ошибка (error указан):
├─> Заказ: status: "declined"
new или expired. Если заказ уже в статусе in_progress, completed или declined, попытка оплаты вернет ошибку. При оплате заказа в статусе expired статус изменится в соответствии с результатом транзакции (completed или declined).expired. Заказ в статусе expired может быть оплачен.completed или declined) заказ не может быть оплачен повторно. Для новой попытки оплаты необходимо создать новый заказ./check возвращает текущий статус заказа. Если заказ в статусе new, он готов к оплате./pay возвращает финальный статус заказа после завершения транзакции (completed или declined).| Код | Описание |
|---|---|
| 200 OK | Запрос успешно обработан |
| 400 Bad Request | Ошибка валидации, проверки подписи или бизнес-логики |
| 500 Internal Server Error | Внутренняя ошибка сервера |
Все ошибки возвращаются в формате JSON:
{
"success": false,
"error": "Описание ошибки"
}
"validation error: order_id or hash_id is required" - не указан ни один из параметров order_id или hash_id (только для эндпоинта /check)"validation error: order_id is required" - не указан обязательный параметр order_id (только для эндпоинта /pay)"validation error: external_id is required" - не указан обязательный параметр external_id (только для эндпоинта /pay)"validation error: X-Key-ID header is required" - не указан заголовок X-Key-ID (обязателен для всех эндпоинтов)"validation error: X-Key-ID not valid" - указанный X-Key-ID не найден в системе или недействителен"validation error: X-Signature header is required" - не указан заголовок X-Signature (обязателен только для эндпоинта /pay)"validation error: check json structure: ..." - ошибка парсинга JSON тела запроса (неверный формат JSON)"validation error: order not found" - заказ с указанным order_id или hash_id не найден для данного X-Key-ID"validation error: resident должен быть 0 или 1, получено: ..." - неверное значение resident в узле account (только для эндпоинта /pay)"validation error: personal_account_number должен быть ровно 11 символов, получено: ..." - неверная длина personal_account_number в узле account (только для эндпоинта /pay)Примечание: Ошибки подписи могут возникать только для эндпоинта /pay.
"signature verification failed: signature is required for key {key_id}, but certificate is empty" - для ключа требуется подпись, но сертификат не настроен (только для эндпоинта /pay)"signature verification failed: failed to decode signature" - неверный формат подписи (не base64 или неверное base64 кодирование). Поддерживаются стандартное и URL-безопасное base64 кодирование (только для эндпоинта /pay)"signature verification failed: public key MD5 hash: {hash}, certificate thumbprint: {thumbprint}, certificate info: {info}" - подпись не прошла проверку. В сообщении об ошибке указаны:
/pay)
"validation error: unsupported public key type" - тип публичного ключа в сертификате не поддерживается. Поддерживается только RSA (только для эндпоинта /pay)"system error" - внутренняя ошибка сервера (может возникать при технических проблемах)"validation error: completed" - заказ уже имеет статус completed и не может быть оплачен"validation error: declined" - заказ имеет статус declined и не может быть оплачен"validation error: in_progress" - заказ находится в процессе оплаты и не может быть оплачен повторно"validation error: expired" - срок действия заказа истек, заказ имеет статус expired. Заказ в статусе expired может быть оплачен через /pay"validation error: transaction amount not match order amount: {order_amount}, {request_amount}" - сумма в запросе не совпадает с суммой заказа"validation error: transaction not found" - транзакция с указанным transaction_id не найдена или не принадлежит указанному заказу (только для эндпоинта /pay)"validation error: transaction status not match order status: {order_status}, {transaction_status}" - статус транзакции не соответствует статусу заказа (только для эндпоинта /pay)"validation error: invalid transaction external id: {transaction_external_id}, {request_external_id}" - указанный external_id в запросе не совпадает с external_id транзакции (только для эндпоинта /pay)Поле user_data позволяет передавать и хранить произвольные данные в формате JSON, связанные с заказом (метаданные, идентификаторы внешних систем и т.д.).
/check возвращает сохранённое значение user_data в ответе. Поле присутствует только если при создании заказа было передано непустое значение.{
"success": true,
"order_id": "550e8400-e29b-41d4-a716-446655440000",
"hash_id": "1234567890",
"amount": 10000,
"phone": "+79991234567",
"description": "Оплата заказа",
"status": "new",
"expired_at": "2024-12-31T23:59:59Z",
"user_data": {"external_ref":"ORD-12345","source":"web"}
}
Для удобства работы с заказами API поддерживает короткий идентификатор hash_id - 10-значную строку, которая генерируется из UUID заказа. Это позволяет использовать более короткий идентификатор вместо полного UUID.
hash_id представляет собой строку из 10 цифр (например, "1234567890")/check указаны оба параметра (order_id и hash_id), поиск выполняется по order_id.Поиск по hash_id:
curl -X POST "https://api.example.com/check" \
-H "X-Key-ID: your-key-id" \
-H "Content-Type: application/json" \
-d '{"hash_id":"1234567890"}'
При возникновении проблем:
X-Key-IDX-Key-IDДля работы с API необходимо сгенерировать пару ключей (приватный ключ и сертификат). Приватный ключ используется для формирования подписи запросов, а сертификат передается администратору API для настройки вашего X-Key-ID.
Выполните команды последовательно:
# 1. Генерация приватного ключа
openssl genrsa -out private_key.pem 2048
# 2. Генерация самоподписанного сертификата
openssl req -new -x509 -key private_key.pem -out certificate.crt -days 36500 \
-subj "/C=RU/ST=Moscow/L=Moscow/O=OOO MAP/CN=OOO MAP"
Параметры команды генерации ключа:
genrsa - команда генерации RSA ключа-out private_key.pem - имя выходного файла с приватным ключом2048 - размер ключа в битах (рекомендуется 2048 или больше)Параметры команды генерации сертификата:
req -new -x509 - создание нового самоподписанного сертификата-key private_key.pem - путь к приватному ключу-out certificate.crt - имя выходного файла с сертификатом-days 36500 - срок действия сертификата в днях (примерно 100 лет)-subj - параметры субъекта сертификата:
C=RU - Country (страна)ST=Moscow - State/Province (регион/область)L=Moscow - Locality/City (город)O=OOO MAP - Organization (организация)CN=OOO MAP - Common Name (имя сертификата)Результат:
private_key.pem - приватный ключ (хранить в безопасности, использовать для формирования подписи)certificate.crt - публичный сертификат (передать администратору API для настройки)Важно:
X-Key-IDopenssl x509 -in certificate.crt -text -noout
openssl x509 -in certificate.crt -noout -dates
# MD5 хеш публичного ключа из сертификата
openssl x509 -noout -modulus -in certificate.crt | openssl md5
# MD5 хеш публичного ключа из приватного ключа
openssl rsa -noout -modulus -in private_key.pem | openssl md5
Хеши должны совпадать, если ключ и сертификат соответствуют друг другу.
Используйте эту команду для проверки соответствия ключа и сертификата, если сервер возвращает следующую ошибку:
{
"success": false,
"error": "signature verification failed: public key MD5 hash: e0916118770af2f7dca5403adf4a9ef9"
}
Сравните MD5 хеш из ошибки с хешем, полученным из вашего приватного ключа. Если хеши не совпадают, значит используется неправильный приватный ключ или сертификат.
Ниже приведен практический пример формирования подписи для запроса к API.
В примерах ниже указаны приватный и публичный ключ (сертификат), соответствующие друг другу. MD5 hash публичного и приватного ключа: e0916118770af2f7dca5403adf4a9ef9.
Тело запроса (payload):
{"order_id":"550e8400-e29b-41d4-a716-446655440000","amount":10000,"external_id":"ext-12345"}
#!/bin/bash
# Тело запроса
PAYLOAD='{"order_id":"550e8400-e29b-41d4-a716-446655440000","amount":10000,"external_id":"ext-12345"}'
# Сохраняем payload
echo -n "$PAYLOAD" > payload.json
# Сохраняем приватный ключ
cat > private_key.pem << 'EOF'
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAsW+Lcu8SSUVHDL0GMsEAOQVkjMrBLoCUcpb+icwbRG8aI+En
OWv5lg6x6tayXR/8accVtKiT9aPeGRW00NGFwm5Uhyx0wlUfAH/ZYWYfbQndRdOI
nI6mEJrgO3Q3lNMhfdXIdVVDij5KGdF7OVfGETRGceqKgXVU6Ku1BiJBsHxf7dKO
/f++kXdVNF4QW7N+tp5LluE/GsA0NNWvRQrM5rlqwstwsCiTbMQugnKRYTy8gKRk
kNLaZma+v/854z9zbtbmCe8iHedLNx4Q9A+kRr5cJDQG1QOsoh95hj62dtlKA8Cp
ZVNil1zrBZ8fqXWG1Q9p4qeg05EwGLbKuPgrHwIDAQABAoIBAE3xlwttE9ZV9WkW
HAPtnmBuCwaCBqyb1RolVDlKDOxZ9dyvCmECGoidefCUUZPw+hupVdKffyeXzXet
flmAwMZxWvZqQ/weEllQ0Dgl+UYX4DjNPKSxUSfYMQpM+iGJQZwabk2En/+5bym6
SOwer6ZdFVjzU9acqSjwTLweDkctD8gsTakDMAp55I3uYClpqJF+9eHyeoLednUj
uhJEsBwaCMhUH3kwmT0RXJdImbOgswRB3tVT9ADnLRTF7fVfWU3H90nscPKQVWK8
XfyJi0t96U9PiPOnS3LLCqdOt7R8TZxGiYy5munHb34WIRDksNnfItNZgXHPtUEW
nH2mgiECgYEA5vsCiar55c3273CWL6RqK9MdgPvNjQw0IiL73PcEVI9106H5xuxQ
w1+843GzxYOcA5Z6hSC4W+rcoVxTUPxeaujd3aI0jjzB1bKhnjnJyzl3devlD82N
g0BH5myWDAL/Drnt+AIuCRhmXA+bL58Sop11Zvy7pHGG6RcF/He+TLECgYEAxKfC
zKjsdXLgM+X9cbBTSs3hmS7qtz8wLMAIA9pGyyOJTEmZkEARTnCd4xmXZ1YfpSN+
PfPGAWny7+xtBqKOj2sLZ1cYAEtPDr+vLBaR7obC8szxwziUkoYXcaT0BNmG208M
5PykpVf+eFxuYscMFA/DqBX2wZomLACmxSEEqM8CgYALXcTFM4Wymk0RgU/SrluP
JodoJnv5+eTC3UfZmso6wwiATpM1B8H9q0NnSdwX1x8hShFjZbXMyCTtR9bNwG2B
A06ProC5kyHSu0SavatBdeV8Bwyxl2LkV5ByNVu44Zjdh6a/MpRDXFEFLLttP32y
RN9XHw64y+FgrQJdZyMVMQKBgCLaVKTu/1FldaTdCwj+JhTo3iXG8eReN4yG0CTW
p5tTBf9WP/gX0rljLihUnce7tMoQu0wBi0Mu4tZwwXXek4OJhjDfd6p9rlo/0Kzw
pxZuHdjoR6TAv1wklb0XbgP6BXOS1Ac1W3zOVpRAVXP+MP7ROGzuz5fKWR+NUgE3
89pzAoGAF9h3ORH0mzEPYPYlZgiVj78aXsySSpz0AIo62qaFTvYUDE6310wdlzkF
zUULvRilHWR0lMEUzij55d/cGx79oJ2sg7jKtBt8Wi2p/JlKlsITiXitOVAUSKmO
p5Qz2mJsvXiNBGZClWBcmOqA97JzIHc4B5V2SPP9JNsAObjsZi4=
-----END RSA PRIVATE KEY-----
EOF
# Вычисляем SHA-256 хеш и подписываем его
SIGNATURE=$(openssl dgst -sha256 -sign private_key.pem payload.json | base64)
# Выводим результат
echo "X-Signature: $SIGNATURE"
# Очистка
rm -f payload.json private_key.pem
После выполнения скрипта вы получите подпись в формате base64, которую нужно использовать в заголовке X-Signature:
X-Signature: JU2Y+dqw1pk5pENGjeos6TjfNPheSUEFh2wjt2QE+QSw+UeQQ38+54VOEtF4VbQPXx2hcpZXmeNcO9vmn+L6VqIrd4G6OTEonYKbde49izWJexIrvC7rTPUf1DTSSQjQcwgjeCTR/VbJ9RcasHv3jPAntPgJe6WnDcTaOiD58TOCIK2onGBJLJrktnhPIqkbQeOwQsytWiu0qYfVOVAJhHmTIHKgfh01aktyFCxZwml1vPuW5S3nXy1286+COSmPCwLqG12WmrXxkj3oAzhvO3JEaABZyzMt8/xlOiWC5SSGgP9OfY2Osk280928K65NNfW8ddG3i78taW7rTpCZRg==
Пример готового запроса:
curl -X POST "https://api.example.com/pay" \
-H "X-Key-ID: your-key-id" \
-H "X-Signature: JU2Y+dqw1pk5pENGjeos6TjfNPheSUEFh2wjt2QE+QSw+UeQQ38+54VOEtF4VbQPXx2hcpZXmeNcO9vmn+L6VqIrd4G6OTEonYKbde49izWJexIrvC7rTPUf1DTSSQjQcwgjeCTR/VbJ9RcasHv3jPAntPgJe6WnDcTaOiD58TOCIK2onGBJLJrktnhPIqkbQeOwQsytWiu0qYfVOVAJhHmTIHKgfh01aktyFCxZwml1vPuW5S3nXy1286+COSmPCwLqG12WmrXxkj3oAzhvO3JEaABZyzMt8/xlOiWC5SSGgP9OfY2Osk280928K65NNfW8ddG3i78taW7rTpCZRg==" \
-H "Content-Type: application/json" \
-d '{"order_id":"550e8400-e29b-41d4-a716-446655440000","amount":10000,"external_id":"ext-12345"}'
Для проверки корректности формирования подписи можно использовать следующий скрипт. Скрипт проверяет, что подпись была создана с помощью приватного ключа, соответствующего публичному ключу из сертификата.
#!/bin/bash
# Параметры
PAYLOAD='{"order_id":"550e8400-e29b-41d4-a716-446655440000","amount":10000,"external_id":"ext-12345"}'
SIGNATURE="JU2Y+dqw1pk5pENGjeos6TjfNPheSUEFh2wjt2QE+QSw+UeQQ38+54VOEtF4VbQPXx2hcpZXmeNcO9vmn+L6VqIrd4G6OTEonYKbde49izWJexIrvC7rTPUf1DTSSQjQcwgjeCTR/VbJ9RcasHv3jPAntPgJe6WnDcTaOiD58TOCIK2onGBJLJrktnhPIqkbQeOwQsytWiu0qYfVOVAJhHmTIHKgfh01aktyFCxZwml1vPuW5S3nXy1286+COSmPCwLqG12WmrXxkj3oAzhvO3JEaABZyzMt8/xlOiWC5SSGgP9OfY2Osk280928K65NNfW8ddG3i78taW7rTpCZRg=="
CERT="-----BEGIN CERTIFICATE-----
MIIDiTCCAnGgAwIBAgIUE1slBc9rLKOtRSAKpTOZuByJ3UswDQYJKoZIhvcNAQEL
BQAwUzELMAkGA1UEBhMCUlUxDzANBgNVBAgMBk1vc2NvdzEPMA0GA1UEBwwGTW9z
Y293MRAwDgYDVQQKDAdPT08gTUFQMRAwDgYDVQQDDAdPT08gTUFQMCAXDTI1MTEw
ODE1MTUwNFoYDzIxMjUxMDE1MTUxNTA0WjBTMQswCQYDVQQGEwJSVTEPMA0GA1UE
CAwGTW9zY293MQ8wDQYDVQQHDAZNb3Njb3cxEDAOBgNVBAoMB09PTyBNQVAxEDAO
BgNVBAMMB09PTyBNQVAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx
b4ty7xJJRUcMvQYywQA5BWSMysEugJRylv6JzBtEbxoj4Sc5a/mWDrHq1rJdH/xp
xxW0qJP1o94ZFbTQ0YXCblSHLHTCVR8Af9lhZh9tCd1F04icjqYQmuA7dDeU0yF9
1ch1VUOKPkoZ0Xs5V8YRNEZx6oqBdVToq7UGIkGwfF/t0o79/76Rd1U0XhBbs362
nkuW4T8awDQ01a9FCszmuWrCy3CwKJNsxC6CcpFhPLyApGSQ0tpmZr6//znjP3Nu
1uYJ7yId50s3HhD0D6RGvlwkNAbVA6yiH3mGPrZ22UoDwKllU2KXXOsFnx+pdYbV
D2nip6DTkTAYtsq4+CsfAgMBAAGjUzBRMB0GA1UdDgQWBBTZpDlJyLzXMhMaBReB
rK2OKvZehDAfBgNVHSMEGDAWgBTZpDlJyLzXMhMaBReBrK2OKvZehDAPBgNVHRMB
Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAZssMBGG4xp7i4zp5ZOOWmYBSS
Wb5DYdytreSRbEeB+mXC2Kp1hZ7sET2YANjTctDX3KS42IreiCK5VUK+JDvIZsE3
25/6eI92QdWIzpjUI9QI92pPgyyPqPhI0GQ7kkHF2HYrsvtNlKD5sA0Q4o6xjZrK
bN4StPPs9qSu+66+PqB9ZRN7F7orOAfa2bmLBOBXpt/3aRb2Ua1+gNYlJSfEF9wP
r6hnARwAZNj20DkxuN36FXqf9BQ07BgieWvYtl9COnaBnM+/pWrPKSyvzU2FR98o
KZxQPNQmDWQ33g149rG6j19rkaZWSvfAR9PbqJI8Rpr1tcnPNE2SiSOtZ9EI
-----END CERTIFICATE-----"
# Временные файлы
TMP_CERT=$(mktemp)
TMP_PUBKEY=$(mktemp)
TMP_SIGNATURE=$(mktemp)
TMP_PAYLOAD=$(mktemp)
trap "rm -f $TMP_CERT $TMP_PUBKEY $TMP_SIGNATURE $TMP_PAYLOAD" EXIT
# Запись сертификата во временный файл
echo "$CERT" > "$TMP_CERT"
# Запись payload во временный файл
echo -n "$PAYLOAD" > "$TMP_PAYLOAD"
# Декодирование base64 подписи во временный файл
if ! echo "$SIGNATURE" | base64 -d > "$TMP_SIGNATURE" 2>/dev/null; then
echo "✗ Ошибка: не удалось декодировать подпись из base64"
exit 1
fi
# Извлечение публичного ключа из сертификата
if ! openssl x509 -in "$TMP_CERT" -pubkey -noout > "$TMP_PUBKEY" 2>/dev/null; then
echo "✗ Ошибка: не удалось извлечь публичный ключ из сертификата"
exit 1
fi
# Проверка подписи (RSA с SHA256, как в коде)
if openssl dgst -sha256 -verify "$TMP_PUBKEY" -signature "$TMP_SIGNATURE" "$TMP_PAYLOAD"; then
echo "✓ Подпись верна"
exit 0
else
echo "✗ Подпись неверна"
exit 1
fi
Скрипт выполняет следующие действия:
openssl dgst для проверки подписи с алгоритмом SHA-256 и RSA PKCS#1 v1.5.verify_signature.sh).chmod +x verify_signature.sh.PAYLOAD, SIGNATURE и CERT на ваши данные../verify_signature.sh.✓ Подпись верна и завершится с кодом 0.✗ Подпись неверна и завершится с кодом 1.