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

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

Все запросы должны содержать в заголовках подпись, которая формируется при помощи RSA-ключа (OpenSSL). Чтобы проверить корректность подписания запросов от партнеров, нужно предоставить публичный (открытый) ключ с соответствующими документами, сопровождающими этот ключ:

  • Акт приёма-передачи открытого ключа
  • Соглашение на использование сервиса
к сведению

Для рабочего слоя с реализацией подписания через OpenSSL ключ должен соответствовать формату RSA и содержать данные юрлица, которое представляет партнёра (в ключе должен содержаться электронный адрес компании и её наименование).

Срок действия RSA-ключа — от 365 до 1825 дней (не более 5 лет).

Создание приватного ключа

Для каждого слоя нужно генерировать отдельный приватный ключ и сертификат с помощью команды:

openssl genrsa -out rsaprivkey.pem 2048
warning

Никому не передавайте приватную часть ключа.

Создание публичного ключа

На основе приватного ключа сформируйте публичный сертификат:

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
base64 -i ./message.sgn

Получаем вывод формата:

ITL85xBoFIKmOYF8O6BCilexlkaSD3NgDiOqRgFtKutxhRXcsqt9RsnIaVHiioB7vnIea4XNgePe3h+lrLfm2SoVJetPZzQTfsrLS4fdblFnnwaOWPRyK9aBxwvHurFeruVZebFOzZ8VYPs6fztsOZX2lkrZ55iiFoaCqu5RDJ3GretYEhc5V9RkrSFOVooVkKs++tLohNJrn1jT0V47e9UI3ZM9Kh2p3R+IlqQgNo2O1CgtDDMd896DoOezFsVEvRs+7nqaKG3d6B8mEICknXCN1Bvs0bqxeN8pLrmCp0H6/s5e4QRx9NGHm8Q3hRbLO7TmLlojRhtodZUuf/Q5Pw==

Отправляем запрос.

Указываем идентификатор ключа, которым формировалась подпись в заголовке Sign-Key-Id. Его передаст сотрудник банка при передаче ключа.

Указываем подпись в формате base64 в заголовке Sign-Body.

к сведению

В Sign-Body не должно быть переносов и других лишних символов.

curl -L 'https://enter.tochka.com/uapi/guarantee/v1.0/create' \
--header 'Sign-Body: 'ITL85xBoFIKmOYF8O6BCilexlkaSD3NgDiOqRgFtKutxhRXcsqt9RsnIaVHiioB7vnIea4XNgePe3h+lrLfm2SoVJetPZzQTfsrLS4fdblFnnwaOWPRyK9aBxwvHurFeruVZebFOzZ8VYPs6fztsOZX2lkrZ55iiFoaCqu5RDJ3GretYEhc5V9RkrSFOVooVkKs++tLohNJrn1jT0V47e9UI3ZM9Kh2p3R+IlqQgNo2O1CgtDDMd896DoOezFsVEvRs+7nqaKG3d6B8mEICknXCN1Bvs0bqxeN8pLrmCp0H6/s5e4QRx9NGHm8Q3hRbLO7TmLlojRhtodZUuf/Q5Pw==' \
--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 base64
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 = base64.b64encode(sign_body).decode() # Подпись запроса в base_64

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,
},
)