Подписание и проверка
Подпись файла
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 текущего окна для ввода логина и пароля для подписания.
- Content-type
-
Error
- Content-type
text/plain - Коды ошибок
- Content-type
Внимание
При получении сообщения об ошибке не следует открывать с ним окно браузера
Подпись файла, передача через 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 текущего окна для ввода логина и пароля для подписания.
- Content-type
-
Error
- Content-type
text/plain - Коды ошибок
- Content-type
Проверка файла
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 готовая форма
- count
- Content-type
- Error
- Content-type
application/json - Коды ошибок
- Content-type
Проверка файла через 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
- Content-type
-
Error
- Content-type
application/json - Коды ошибок
- Content-type
Проверка нескольких файлов через 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
- Content-type
- Error
- Content-type
application/json - Коды ошибок
- Content-type
Быстрая проверка факта подписания запроса
URL https://server_name/signapi/check/добавочная_часть
Request
- Method
GET
Response
- Success
- Content-type
application/json - Body
JSON- status
- "0" - не подписан
- "1" - подписан
- "2" - отклонен
- "3" - файл удален
- comment - причина отклонения, если есть
- status
- Content-type
- Error
- Content-type
application/json - Коды ошибок
- Content-type
Быстрая проверка факта подписания нескольких файлов
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” - причина отклонения, если есть
- status
- Content-type
- Error
- Content-type
application/json - Коды ошибок
- Content-type
Отказ от подписи запроса
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)
- Content-type
- Error
- Content-type
application/json - Коды ошибок
- Content-type
Отказ от подписи нескольких запросов
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)
- Content-type
- Error
- Content-type
application/json - Коды ошибок
- Content-type
Проверка наличия подписей у файла
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 - нет подписей
- Content-type
- Error
- Content-type
text/plain - Body
TEXT- 0 - при проверке произошла ошибка
- Content-type
Получение нескольких подписей по хешу файла
URL https://server_name/signaturecheck/get_pkcs/hash/[[filehash]]
Request
- Method
GET
Response
- Success
- Content-type
application/json - Body
JSON- signatures = array of
- ссылка на pkcs контейнер подписи
- signatures = array of
- Content-type
Получение нескольких подписей по содержимому файла
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 контейнер подписи
- signatures = array of
- Content-type
Получение групповой подписи по хешу файла
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
- Success
- Content-type
application/pkcs7-mime - Content-Disposition
attachment
- Content-type
- Error
Получение групповой присоединенной подписи
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
- Content-type
Получение подписи в формате CADES T
URL https://server_name/signaturecheck/get_t_pkcs/hash/[[filehash]]/[[user_id]]
Request
- Method
GET
Response
- Success
- Content-type
application/pkcs7-mime - Content-Disposition:
attachment
- Content-type
- Error
Получение подписи в формате CADES XLT1
URL https://server_name/signaturecheck/get_xlt_pkcs/hash/[[filehash]]/[[user_id]]
Request
- Method
GET
Response
- Success
- Content-type
application/pkcs7-mime - Content-Disposition
attachment
- Content-type
- Error
Получение групповой подписи в формате CADES XLT1
URL https://server_name/signaturecheck/get_xlt_grp/hash/[[filehash]]
Request
- Method
GET
Response
- Success
- Content-type
application/pkcs7-mime - Content-Disposition
attachment
- Content-type
- Error
Отказы при получении подписи по хешу
Относится к четырём методам выше: 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 пакета в нем не обнаружено элемента массива с ключем fileterror 2: no filenameПосле раскодирования JSON пакета в нем не обнаружено элемента массива с ключем fnameerror 3: wrong fileПришедшее в массиве содержимое по ключу filet не получается раскодировать base64_decodeerror 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 status409) Запрос с теми же документами уже выполняется. Возникает, если новый запрос на подпись (sjson/multijson/multipart) с тем же содержимым отправлен до завершения предыдущего. Не отправляйте повторный запрос, пока не получен ответ предыдущего; при получении этого кода дождитесь окончания и при необходимости повторите запрос — дубликат запроса при этом не создается.
Сообщения об ошибках при проверке
HTTP status 200
error 1: wrong base64Пришедшее в запросе содержимое по ключу filet не получается раскодировать base64_decodeerror 2: wrong md5Не получается вычислить md5 от раскодированного файла, свяжитесь с разработчикамиerror 3: wrong fileПришедшее в запросе содержимое по ключу filet не получается раскодировать base64_decodeerror 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 хеш от содержимого файла