Перейти к основному содержимому

Подписание запросов

Все запросы должны содержать в заголовках подпись, которая формируется при помощи 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,
},
)