Перейти к содержанию

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

Подпись файла

URL https://server_name/signapi/sjson

Request

  • Method POST
  • Content-type application/json
  • Body JSON
    • key = полученный ключ доступа
    • filet = base64_encode( содержимое файла )
    • fname = имя файла
    • Идентификатор для определения подписанта файла:
    • user_email = email пользователя, подписывающего файл
    • user_ph = телефон пользователя, подписывающего файл
    • user_snils = СНИЛС пользователя, подписывающего файл
    • company_inn = ИНН компании, подписывающей файл
    • company_ogrn = ОГРН компании, подписывающей файл
    • company_kpp = КПП компании, подавать вместе с ИНН или ОГРН
    • Далее идут дополнительные параметры, которые не обязательно использовать:
    • md5 = хеш содержимого для проверки
    • url = адрес возврата после подписания
    • push_key = push_key = id ключа для отправки PUSH-уведомления в мобильное устройство, при переходе по которому сразу откроется экран подписания. Ключ должен быть мобильным, ID можно взять из АПИ "Сертификаты" - "Сертификаты пользователя"
    • noemail = 1, если нужно не высылать пользователю емеил
    • nopush = 1, если не нужно высылать пользователю push на устройство
    • forcesms = 1, если необходима двухфакторная авторизация при подписании серверный НКЭП
    • IF = 1, если необходимо уведомление на url-оповещения[^2] при каждом подписании [^3]
    • personal = 1, если для файла нужно отображать только подписи самого пользователя

Response

  • Success

    • Content-type text/plain
    • В ответ приходит добавочная часть url. В этот момент пользователь получает документ на подпись. Если подпись мобильная, вы можете сформировать ссылку вида https://server_name/signapi/sjson/добавочная_часть и открыть ее для отправки PUSH-уведомления. Если подпись серверная, вам нужно открывать ссылку вида https://server_name/signapi/sjson/добавочная_часть в браузере или iframe текущего окна для ввода логина и пароля для подписания.
  • Error

Внимание

При получении сообщения об ошибке не следует открывать с ним окно браузера

Подпись файла, передача через multipart/form-data

URL https://server_name/signapi/multipart

  • Method POST
  • Content-type multipart/form-data

Все ключи совпадают с sjson, только вместо filet нужно передавать файл в $_FILES["file"]

Также поддерживается множество файлов, имена должны идти в том же порядке, что и файлы. При передаче нескольких файлов пофайловые ключи (fname, md5, desc, from_hash, payload, personal) также передаются по одному значению на каждый файл в том же порядке, например:

curl -X POST 'https://server_name/signapi/multipart' \ --header 'Content-Type: multipart/form-data' \ --form 'key=%APIKEY%' \ --form 'user_ph=+79001234567' \ --form file[]=@1.pdf \ --form 'fname[]=1.pdf' \ --form 'personal[]=1' \ --form file[]=@2.pdf \ --form 'fname[]=2.pdf' \ --form 'personal[]=0' \

Дополнительный ключ:

  • multi = 1, чтобы ответ всегда приходил в формате multijson (UUID группы), даже если передан один файл

Возврат совпадает с sjson или multijson если передано множество файлов

Внимание

Без multi=1 формат ответа зависит от количества файлов: один файл — добавочная часть url вида id/hash, как в sjson; несколько файлов — UUID группы, как в multijson. Проверяются они разными эндпоинтами: /signapi/check/id/hash и /signapi/multicheck/UUID соответственно. Если ваша интеграция всегда ожидает UUID группы, передавайте multi=1.

Подпись нескольких файлов

URL https://server_name/signapi/multijson

Request

  • Method POST
  • Content-type application/json
  • Body JSON
    • key = полученный ключ доступа
    • files = array of
      • filet = base64_encode( содержимое файла )
      • fname = имя файла
      • md5 = хеш содержимого для проверки
      • personal = 1, если для файла нужно отображать только подписи самого пользователя
    • multiname = имя пакета для отображения в мобильном приложении
    • Идентификатор для определения подписанта файла:
    • user_email = email пользователя, подписывающего файл
    • user_ph = телефон пользователя, подписывающего файл
    • user_snils = СНИЛС пользователя, подписывающего файл
    • company_inn = ИНН компании, подписывающей файл
    • company_ogrn = ОГРН компании, подписывающей файл
    • company_kpp = КПП компании, подавать вместе с ИНН или ОГРН
    • Далее идут дополнительные параметры, которые не обязательно использовать:
    • url = адрес возврата после подписания
    • push_key = push_key = id ключа для отправки PUSH-уведомления в мобильное устройство, при переходе по которому сразу откроется экран подписания. Ключ должен быть мобильным, ID можно взять из АПИ "Сертификаты" - "Сертификаты пользователя"
    • noemail = 1, если нужно не высылать пользователю емеил
    • nopush = 1, если не нужно высылать пользователю push на устройство
    • forcesms = 1, если необходима двухфакторная авторизация при подписании серверный НКЭП
    • IF = 1, если необходимо уведомление на url-оповещения[^2] при каждом подписании [^3]

Response

  • Success

    • Content-type text/plain
    • UUID (uuid1, строка 8-4-4-4-12 символов)В этот момент пользователь получает документ на подпись. Если подпись мобильная, вы можете сформировать ссылку вида https://server_name/signapi/multijson/UUID и открыть ее для отправки PUSH-уведомления. Если подпись серверная, вам нужно открывать ссылку вида https://server_name/signapi/multijson/UUID в браузере или iframe текущего окна для ввода логина и пароля для подписания.
  • Error

Проверка файла

URL https://server_name/signaturecheck/json Request

  • Method POST
  • Content-type application/json
  • Body JSON
    • md5 = md5( содержимое файла )
    • Далее идут параметры, которые нужно передавать только для получения печатной формы (документ со штампом подписи):
    • filet = base64_encode( содержимое файла )
    • если подан filet и нужна печатная форма для поддерживаемых типов документов, на данный момент: *.pdf
      • pdf_email - email на который будет отправлена печатная форма
      • pdf_url - url с обработчиком, который примет печатную форму, на него придет запрос в формате id={pdf_id} и $_FILES[{pdf_id}]=форма
      • pdf - в ответ в "pdf" придет base64 готовая форма, может не работать на больших файлах, используйте первые два способа

Response

  • Success
    • Content-type application/json
    • Body JSON
      • count
        • i - количество подписей
        • 0 - если файл не подписан
      • signature_i — нумерация с единицы: первая подпись в signature_1, последняя в signature_{count}
        • alg = алгоритм
        • value = base64_encode( значение подписи )
        • pkcs7 = web_link (Ссылка на скачивание pkcs7-контейнера)
        • pkcs64 = base64_encode( pkcs7 контейнер электронной подписи)
        • sigdate = дата подписи
        • timestamp = ссылка на метку доверенного времени
      • person
        • public_key = base64_encode( открытый ключ )
        • key_id = номер ключа
        • crt_id = номер сертификата
        • crt_status
          • 0 — действителен
          • 1 — ожидается
          • 2 — приостановлен
          • 3 — отозван
          • 4 — отсутствует
          • 5 — ошибка (чаще всего используются только 0 и 3)
        • cr_date = дата создания сертификата - dd.mm.yyyy
        • exp_date = дата истечения сертификата - dd.mm.yyyy
        • passport =
          • name = имя
          • lastname = отчество
          • surname = фамилия
        • phone_number = телефон
        • email_address = email
        • snils = СНИЛС
        • nid = номер заявки пользователя
      • company если подпись от имени компании
        • name = название
        • inn = ИНН
        • ogrn = ОГРН
      • pdf = {pdf_id} int - для обработки ответа по pdf_url или base64 готовая форма
  • Error

Проверка файла через iframe

URL https://server_name/signaturecheck/request

Request

  • Method POST
  • Content-type application/json
  • Body JSON
    • key = полученный ключ доступа
    • hash = md5( содержимое файла )

Response

  • Success

    • Content-type text/plain
    • Ответ UUID (uuid1, строка 8-4-4-4-12 символов) Результаты проверки по адресам https://server_name/signaturecheck/result/UUID страница в дизайне signme По этому адресу результат будет доступен для открытия только один раз. Для повторного открытия необходимо повторить процедуру повторно. https://server_name/signaturecheck/iframe/UUID javascript для отрисовки iframe
  • Error

Проверка нескольких файлов через iframe

URL https://server_name/signaturecheck/multi

Request

  • Method POST
  • Content-type application/json
  • Body JSON
    • key = полученный ключ доступа
    • files = array of
      • hash = md5( содержимое файла )
      • name = имя файла, необязательно

Response

  • Success
    • Content-type text/plain
    • UUID (uuid1, строка 8-4-4-4-12 символов) Результаты проверки по адресам https://server_name/signaturecheck/result/UUID/1 (обратите внимание на отличие от предыдущего /1) страница в дизайне Sign.Me По этому адресу результат будет доступен для открытия только один раз. Для повторного открытия необходимо повторить процедуру повторно. https://server_name/signaturecheck/multiiframe/UUID javascript для отрисовки iframe
  • Error

Быстрая проверка факта подписания запроса

URL https://server_name/signapi/check/добавочная_часть

Request

  • Method GET

Response

  • Success
    • Content-type application/json
    • Body JSON
      • status
        • "0" - не подписан
        • "1" - подписан
        • "2" - отклонен
        • "3" - файл удален
      • comment - причина отклонения, если есть
  • Error

Быстрая проверка факта подписания нескольких файлов

URL https://server_name/signapi/multicheck/UUID

Request

  • Method GET

Response

  • Success
    • Content-type application/json
    • Body JSON
      • status
        • "0" - не подписан
        • "1" - подписан
        • "2" - отклонен
        • "3" - файл удален
        • "4" - подписаны не все файлы из запроса
        • "5" - мультизпрос в процессе подписи, повторите проверку позже
      • comment” - причина отклонения, если есть
  • Error

Отказ от подписи запроса

URL https://server_name/signapi/reject

Request

  • Method POST
  • Content-type application/json
  • Body JSON
    • rid = id запроса (первая половина добавочной_части)
    • key = полученный ключ доступа
    • reason = текст причины отказа

Response

  • Success
    • Content-type application/json
    • Body JSON
      • result = one of
      • already_rejected
      • already_signed
      • wrong_reason — причина отказа не передана или пуста
      • wrong_source
      • wrong_source_or_id
      • wrong_method
      • 0
      • date = дата отказа или подписания запроса(если already_rejected, already_signed или 0)
      • reason = причина отказа (если already_rejected или 0)
  • Error

Отказ от подписи нескольких запросов

URL https://server_name/signapi/multireject/UUID

Request

  • Method POST
  • Content-type application/json
  • Body JSON
  • key = полученный ключ доступа
  • reason = текст причины отказа

Response

  • Success
    • Content-type application/json
    • Body JSON
      • result = one of
      • already_rejected — все запросы группы уже отклонены
      • already_signed — хотя бы один запрос группы уже подписан
      • wrong_reason — причина отказа не передана или пуста
      • wrong_source
      • wrong_source_or_id
      • wrong_id — группа существует, но запросов в ней нет
      • wrong_method
      • 0
      • lastdate = дата отказа или подписания запроса для последнего файла из группы (если already_rejected, already_signed или 0)
      • lastreason = причина отказа для последнего файла из группы (если already_rejected или 0)
  • Error

Проверка наличия подписей у файла

URL https://server_name/signaturecheck/precheck

Request

  • Method POST
  • Content-type application/json
  • Body JSON
    • key = полученный ключ доступа
    • hash = хеш файла
    • user_id = идентификатор пользователя
    • company_id = идентификатор компании
    • key_id = идентификатор ключа подписания

Response

  • Success
    • Content-type text/plain
    • Body TEXT
      • 1 - есть хотя бы одна подпись
      • 0 - нет подписей
  • Error
    • Content-type text/plain
    • Body TEXT
      • 0 - при проверке произошла ошибка

Получение нескольких подписей по хешу файла

URL https://server_name/signaturecheck/get_pkcs/hash/[[filehash]]

Request

  • Method GET

Response

  • Success
    • Content-type application/json
    • Body JSON
      • signatures = array of
        • ссылка на pkcs контейнер подписи

Получение нескольких подписей по содержимому файла

URL https://server_name/signaturecheck/get_pkcs/file

Request

  • Method POST
  • Content-type multipart/form-data
  • Body FORM
    • key = полученный ключ доступа
    • file = бинарное содержимое файла

Response

  • Success
    • Content-type application/json
    • Body JSON
      • signatures = array of
        • ссылка на pkcs контейнер подписи

Получение групповой подписи по хешу файла

URL https://server_name/signaturecheck/get_grp_pkcs/hash/[[filehash]]/[[algorithm]]

Request

  • Method GET
  • Params
    • filehash - хеш подписанного файла
    • algorithm - алгоритм подписи. Может принимать одно из следующих значений:
      • 2 = ГОСТ-34.10-2012_256 УКЭП
      • 3 = ГОСТ-34.10-2012_512 УКЭП
      • 5 = ГОСТ-34.10-2012_256 НКЭП
      • 6 = ГОСТ-34.10-2012_512 НКЭП

Response

Получение групповой присоединенной подписи

URL https://server_name/signaturecheck/attach

Request

  • Method POST
  • Content-type multipart/form-data
  • Body FORMDATA
    • key = полученный ключ доступа
    • file = бинарное содержимое файла

Response

  • Success
    • Content-type application/pkcs7-mime
    • Content-Disposition attachment

Получение подписи в формате CADES T

URL https://server_name/signaturecheck/get_t_pkcs/hash/[[filehash]]/[[user_id]]

Request

  • Method GET

Response

Получение подписи в формате CADES XLT1

URL https://server_name/signaturecheck/get_xlt_pkcs/hash/[[filehash]]/[[user_id]] Request

  • Method GET

Response

Получение групповой подписи в формате CADES XLT1

URL https://server_name/signaturecheck/get_xlt_grp/hash/[[filehash]]

Request

  • Method GET

Response

Отказы при получении подписи по хешу

Относится к четырём методам выше: get_grp_pkcs, get_t_pkcs, get_xlt_pkcs и get_xlt_grp.

Код ответа различает две разные ситуации, и обрабатывать их нужно по-разному.

  • 404 — запрошенного нет. Неизвестный хеш, у файла нет подписей, не найден пользователь. Ответ не изменится, повторять запрос бессмысленно.
  • 500 — подпись есть, но выдать её не удалось. Форматы CAdES-T и CAdES-XLT1 собираются в момент запроса, и для этого нужны чужие службы: OCSP удостоверяющего центра и служба меток времени. Когда они не отвечают, документ подписан, а ответить нечем. Повторите запрос позже. Считать документ неподписанным при этом коде нельзя.

Раньше оба случая отдавали 404, и отличить их было невозможно.

Причина отказа приходит в теле. С заголовком X-Error-Json — в JSON:

{"error": {"code": "NOXLT", "message": "не удалось собрать подпись: внешняя служба не ответила"}}

Без заголовка — строкой error <код>: <причина>.

Сообщение короткое и без технических подробностей: какая именно служба не ответила и по какому сертификату, остаётся в наших логах. Ориентируйтесь на code и HTTP-статус, разбирать текст сообщения не нужно — он может меняться.

Код HTTP Что произошло
FHASH 404 Файл с таким хешем не найден
NOSIG, GPKCS_NOSIG 404 У файла нет подписей
NOUSER 404 Пользователь с таким идентификатором не найден
NOPKCS 404 У пользователя нет подписи этого файла
GPKCS_NOHASH, GPKCS_NOFILE 404 Файл по хешу не найден
GPKCS_ALG 404 Неизвестный алгоритм подписи
NOXLT, GPKCS 404 У подписей нет файлов — собирать нечего
NOXLT 500 Не удалось собрать XLT: не ответил OCSP или служба меток времени
GRPXLT, GPKCS 500 Не удалось собрать групповую подпись
T 500 Не удалось построить CAdES-T
NOTSA 500 Служба меток времени недоступна

Один и тот же код может прийти с разным HTTP-статусом: NOXLT с 404 означает, что собирать не из чего, а с 500 — что сборка не удалась. Ориентируйтесь на статус.

Сообщения об ошибках при подписи

HTTP status 200

  • error 1: no file После раскодирования JSON пакета в нем не обнаружено элемента массива с ключем filet
  • error 2: no filename После раскодирования JSON пакета в нем не обнаружено элемента массива с ключем fname
  • error 3: wrong file Пришедшее в массиве содержимое по ключу filet не получается раскодировать base64_decode
  • error 5: cant create file Файл не удалось принять. Кроме сбоя записи на сервер, этот же код приходит в двух случаях, которые исправляются на стороне ИС: в одном запросе дважды передан один и тот же файл с одним именем, либо присланный md5 не совпал ни с одним из хешей полученного файла.
  • error 6: cant create request Не получается создать запрос на подпись файла на сервере - в любом случае свяжитесь с разработчиками
  • error 6: wrong user phone | wrong user email | wrong user snils | wrong user id | wrong user key Пользователь с таким телефоном/email/СНИЛС/идентификатором/ключом не зарегистрирован или не активирован. Текст называет то поле, по которому искали.
  • error 6: wrong company inn | wrong company ogrn | wrong company id Компания с таким ИНН/ОГРН/идентификатором не зарегистрирована или не активирована
  • error 7: get api key Апи ключ отсутствует или не найден в разрешенных
  • error 12: request already in progress (HTTP status 409) Запрос с теми же документами уже выполняется. Возникает, если новый запрос на подпись (sjson/multijson/multipart) с тем же содержимым отправлен до завершения предыдущего. Не отправляйте повторный запрос, пока не получен ответ предыдущего; при получении этого кода дождитесь окончания и при необходимости повторите запрос — дубликат запроса при этом не создается.

Сообщения об ошибках при проверке

HTTP status 200

  • error 1: wrong base64 Пришедшее в запросе содержимое по ключу filet не получается раскодировать base64_decode
  • error 2: wrong md5 Не получается вычислить md5 от раскодированного файла, свяжитесь с разработчиками
  • error 3: wrong file Пришедшее в запросе содержимое по ключу filet не получается раскодировать base64_decode
  • error 4: wrong hash Пришедшее в запросе значение md5 не совпадает с вычисленным на сервере
  • error 5: no hash Значение md5 отсутствует в запросе

Сообщения об ошибках при запросе iframe

Первые два случая отвечают не телом error N: ... — у них свой HTTP-статус, и проверять их надо по нему.

HTTP status 400

  • wrong json (причина) Тело запроса не разбирается: не JSON, не тот Content-Type либо JSON не является объектом. Причина указана в скобках.

HTTP status 401

  • Invalid API key Значение в поле key не соответствует ключу для данной ИС, ИС не зарегистрирована либо её счёт отключён.

HTTP status 200

  • error 3: wrong hash Означает, что md5 прислан в неправильном формате (не соответствует регулярному выражению a-zA-Z0-9, содержит недопустимые символы)
  • error 4: request not created Не получается создать запрос на проверку файла на сервере - в любом случае свяжитесь с разработчиками

Возврат на url

Если указан url, то после подписи произойдет возврат на этот урл + добавочная часть вида ?signed=true или ?signed=false&error=%errno% (в случае, если в url уже есть символ ? часть будет начинаться с &)

errno

  • 1 пароль неправильный
  • 2 смс код неправильный
  • 3 пользователь не имеет права подписывать
  • 4 в компании стоит запрет первой подписи
  • 5 запрос отклонен
  • 6 внутренняя ошибка сервера, запишите точное время ошибки
  • 7 попытка подписи от имени другой компании

Если url начинается с символов GET: (4 символа дословно), а далее идет сам url, например:

GET:https://test.sign.me/push

то произойдет HTTP запрос с нашего сервера по тем же правилам (добавочная часть), но без переадресаций и открытия страниц. Это можно использовать для уведомлений при подписании из мобильного приложения.

[^2]: url-оповещения задается один раз. Он сообщается сотрудникам Sign.Me [^3]: На url будет осуществляться GET запрос с параметрами 'apikey': ваш апи ключ, 'md5hash': md5 от содержимого файла, 'gosthash': ГОСТ 34.11 хеш от содержимого файла