Подписание запросов
Все запросы должны содержать в заголовках подпись, которая формируется при помощи RSA-ключа (OpenSSL). Чтобы проверить корректность подписания запросов от партнеров, нужно предоставить публичный (открытый) ключ с соответствующими документами, сопровождающими этот ключ:
- Акт приёма-передачи открытого ключа
- Соглашение на использование сервиса
Для рабочего слоя с реализацией подписания через OpenSSL ключ должен соответствовать формату RSA и содержать данные юрлица, которое представляет партнёра (в ключе должен содержаться электронный адрес компании и её наименование).
Срок действия RSA-ключа — от 365 до 1825 дней (не более 5 лет).
Создание приватного ключа
Для каждого слоя нужно генерировать отдельный приватный ключ и сертификат с помощью команды:
openssl genrsa -out rsaprivkey.pem 2048
Никому не передавайте приватную часть ключа.
Создание публичного ключа
На основе приватного ключа сформируйте публичный сертификат:
openssl req -days 1825 -new -x509 -key rsaprivkey.pem -out rsaacert.pem
Параметр days задаёт нужный срок действия в днях. Его нужно передать сотрудникам банка, отвечающим за сервис.
Файл rsaacert.pem содержит публичную часть ключа, которая выглядит так:
-----BEGIN CERTIFICATE-----
MIIDazCCAlOgAwIBAgIUOMamoGWXd5FATOQzf74j2tP6tWAwDQYJKoZIhvcNAQEL
...
-----END CERTIFICATE-----
Подписание запроса
Сформируйте запрос в виде строки следующего формата:
'{"Data": {"guaranteeType": "FULFILLMENT", "guaranteeStartDate": "string", "guaranteeEndDate": "string", "guaranteeSum": 0, "clientInn": "string", "tenderCustomerInn": "string", "purchaseType": 0}}'
- В запросе не должно быть переносов и табуляций
- Ключ и его значение должны разделяться двоеточием и пробелом
- Пары «ключ-значение» должны разделяться запятой и пробелом
Пример кода на python, который формирует корректную строку:
import json
request_payload = {
"Data": {
"guaranteeType": "FULFILLMENT",
"guaranteeStartDate": "string",
"guaranteeEndDate": "string",
"guaranteeSum": 0,
"clientInn": "string",
"tenderCustomerInn": "string",
"purchaseType": 0
}
}
sign_payload = json.dumps(request_payload) # Сообщение для подписи
print(sign_payload)
Пример формирования подписи через командную строку
Помещаем сформированную строку с запросом в файл message:
echo -n '{"Data": {"guaranteeType": "FULFILLMENT", "guaranteeStartDate": "string", "guaranteeEndDate": "string", "guaranteeSum": 0, "clientInn": "string", "tenderCustomerInn": "string", "purchaseType": 0}}' > message
Подписываем сообщения, используя алгоритм sha256. Это создаст бинарный файл message.sgn, содержащий подпись.
openssl dgst -sha256 -sign ./rsaprivkey.pem -out ./message.sgn ./message
Кодируем в формате hex:
xxd -p ./message.sgn | tr -d '\n'
Получаем вывод формата:
535af0bf2024cb2775f317cd546da2d87b88f3d5dbc9f0ae3c836c6a086d487118416ecff242c6660f5d39c7fffa11d0c40b772f1bbd9bebec7ba3d45333d89fe9ffc1994596bbb7fc7425ff302409082348dbcefe99bc764a8ee0a8d14d3e76afc1e00fc31b68adc24ca5fe39af4f747fd87df2eef9ec5605726d74820d8f0c5eceb585c73a14f223804d1a2150e522875a4916517df63cd3d909edb3a2d8eac37699cffba532ff599959803272a4ac9df823aa5c5054fb651f65b18e43031b01c197346a09adebcfa0fe710699409389409997302022af0835539492f3fd14c841aec58345f49c4bf8b2bd642f700fb89a6748891687f0dfbcdb46756232e0
Отправляем запрос.
Указываем идентификатор ключа, которым формировалась подпись в заголовке Sign-Key-Id. Его передаст сотрудник банка
при передаче ключа.
Указываем подпись в формате hex в заголовке Sign-Body.
В Sign-Body не должно быть переносов и других лишних символов.
curl -L 'https://enter.tochka.com/uapi/guarantee/v1.0/create' \
--header 'Sign-Body: '535af0bf2024cb2775f317cd546da2d87b88f3d5dbc9f0ae3c836c6a086d487118416ecff242c6660f5d39c7fffa11d0c40b772f1bbd9bebec7ba3d45333d89fe9ffc1994596bbb7fc7425ff302409082348dbcefe99bc764a8ee0a8d14d3e76afc1e00fc31b68adc24ca5fe39af4f747fd87df2eef9ec5605726d74820d8f0c5eceb585c73a14f223804d1a2150e522875a4916517df63cd3d909edb3a2d8eac37699cffba532ff599959803272a4ac9df823aa5c5054fb651f65b18e43031b01c197346a09adebcfa0fe710699409389409997302022af0835539492f3fd14c841aec58345f49c4bf8b2bd642f700fb89a6748891687f0dfbcdb46756232e0' \
--header 'Sign-Key-Id: 66019375-5ae8-4618-bf10-919547a269df' \
--header 'Content-Type: application/json' \
--data-binary @'./message'
Пример формирования подписи через код на python
Для выполнения этого кода необходимо по инструкции выше сформировать приватный ключ rsaprivkey.pem и установить
библиотеки pycryptodome и httpx:
pip install pycryptodome
pip install httpx
import binascii
import json
import httpx
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA
from Crypto.PublicKey.RSA import RsaKey
from Crypto.Signature import PKCS1_v1_5
from httpx import BasicAuth
def sign(message: bytes, private_key_: RsaKey) -> bytes:
signer = PKCS1_v1_5.new(private_key_)
data_hash = SHA256.new(message)
return signer.sign(data_hash)
with open('rsaprivkey.pem', 'rb') as key_file:
private_key = RSA.import_key(key_file.read())
request_payload = {
'Data': {
'guaranteeType': 'FULFILLMENT',
'guaranteeStartDate': "string',
'guaranteeEndDate': "string',
'guaranteeSum': 0,
'clientInn': 'string',
'tenderCustomerInn': 'string',
'purchaseType': 0
}
}
sign_payload = json.dumps(request_payload) # body запроса в корректном строковом формате
sign_body = sign(sign_payload.encode('utf-8'), private_key) # Подпись запроса
encoded_sign_body = binascii.hexlify(sign_bytes).decode('utf-8') # Подпись запроса в hex
response = httpx.post(
'https://stage-openapi.bank24.int/uapi/guarantee/v1.0/create',
json=request_payload,
headers={
'Sign-Key-Id': 'Указать идентификатор ключа',
'Sign-Body': encoded_sign_body,
},
)