GPLVote Sign Doc Direct API
Админ (обсуждение | вклад) (Новая страница: «=== Общее описание === В мобильном приложении встроена возможность взаимодействовать с сай...») |
Админ (обсуждение | вклад) (→Запрос на регистрацию подписи на сайте клиента) |
||
(не показаны 15 промежуточных версий 1 участника) | |||
Строка 3: | Строка 3: | ||
В мобильном приложении встроена возможность взаимодействовать с сайтом клиента напрямую через URL в ссылках или QR-кодах. При этом приложению передается информация о прямых ссылках на сайт-клиент и взаимодействие происходит минуя прокси-сервера. | В мобильном приложении встроена возможность взаимодействовать с сайтом клиента напрямую через URL в ссылках или QR-кодах. При этом приложению передается информация о прямых ссылках на сайт-клиент и взаимодействие происходит минуя прокси-сервера. | ||
− | === | + | === Криптография === |
− | + | Ключ пользователя представляет из себя пару RSA ключей размером не менее 2048 бит. Идентификатор ключа пользователя формируется через получение хэша SHA-256 от бинарного представления публичного ключа пользователя. Идентификатор представляется в кодировке BASE64 без переводов строк. | |
+ | Подпись представляет собой двоичную ЭЦП "SHA256withRSA" (тип подписи передается на сайт в атрибуте "sign_type"), представленную в кодировке BASE64 без переводов строк. | ||
+ | |||
+ | Зашифрованные данные в случае, если их размер меньше 2048 бит (256 байт), шифруются публичным RSA ключем пользователя "как есть". Если данные размером больше чем 256 байт, то их шифрование происходит с помощью алгоритма AES со случайным ключем (256 бит). Причем, в этом случае в начале зашифрованных данных идет блок из 256 байт, зашифрованный открытым RSA ключем пользователя, который содержит: байты 0-31 (32 байта) - случайный AES ключ, байты 32-47 (16 байт) - случайный AES IV, байты 48-79 (32 байта) - CRC в виде хэша SHA256 от шифруемых данных (данных в открытом виде). Дальше содержаться сами данные, алгоритм шифрования которых "AES/CBC/PKCS5Padding". В конечном виде бинарные зашифрованные данные представляются в виде BASE64 без переводов строк. | ||
+ | |||
+ | В качестве строки для формирования электронной подписи документа используется | ||
+ | |||
+ | $doc['site'].":".$doc['doc_id'].":".$doc['dec_data'].":".$doc['template'] | ||
+ | |||
+ | === Ключ отмены (аннулирования) === | ||
+ | |||
+ | "Ключ отмены" генерируется случайным образом одновременно с генерированием основного ключа. Ключ отмены служит для того, что-бы владелец мог объявить рабочий ключ скомпрометированным и не действующим. Для этого во всех пакетах регистрации публичного ключа присутствует два поля - cancel_public_key и cancel_public_key_sign. В первом содержится публичная часть ключа отмены. Во втором - подпись публичного ключа отмены основным ключем (привязка ключа отмены к основному ключу). В случае необходимости сообщить об отмене (аннулировании) ключа, пользователю необходимо любым из способов сформировать и отправить на все сайты, использующие его ключ, следующий пакет: | ||
+ | |||
+ | { | ||
+ | "type": "CANCEL", | ||
+ | "user_key_id": "<идентификатор основного публичного ключа пользователя подлежащего отмене>", | ||
+ | "cancel_time": "<момент отмены в формате UNIXTIME в таймзоне GMT>", | ||
+ | "cancel_sign": "<подпись строки со временем отмены секретным ключем отмены пользователя в кодировке BASE64 без переводов строк>", | ||
+ | "cancel_sign_type": "<тип подписи (например "SHA256withRSA")>" | ||
+ | } | ||
+ | |||
+ | === Запрос на регистрацию подписи на сайте клиента === | ||
+ | |||
+ | Для инициирования процедуры регистрации подписи на сайте клиента в приложение необходимо передать (например, с помощью QR-кода) следующий URL: | ||
+ | <pre> | ||
signreg://<домен сайта-клиента>/<путь регистрации подписи на сайте клиента>?code=<одноразовый код для регистрации>&site=<идентификатор сайта клиента> | signreg://<домен сайта-клиента>/<путь регистрации подписи на сайте клиента>?code=<одноразовый код для регистрации>&site=<идентификатор сайта клиента> | ||
+ | </pre> | ||
− | + | ВАЖНО!!! Т.к. одноразовый код подписывается приложением автоматически, для его вида существуют жесткие ограничения: одноразовый код должен состоять только из цифр и быть размером не более 16 символов. | |
+ | URL по которому приложение будет передавать регистрацию подписи, составляется в виде: | ||
+ | <pre> | ||
http://<домен сайта-клиента>/<путь регистрации подписи на сайте клиента> | http://<домен сайта-клиента>/<путь регистрации подписи на сайте клиента> | ||
− | + | </pre> | |
По этому URL будет выполнен POST запрос с передачей в нем следующего документа о регистрации подписи в виде JSON документа: | По этому URL будет выполнен POST запрос с передачей в нем следующего документа о регистрации подписи в виде JSON документа: | ||
Строка 20: | Строка 47: | ||
"code": "<одноразовый код для регистрации подписи>", | "code": "<одноразовый код для регистрации подписи>", | ||
"public_key": "<публичный ключ пользователя в кодировке Base64 без переводов строк>", | "public_key": "<публичный ключ пользователя в кодировке Base64 без переводов строк>", | ||
− | "sign": "<подпись строки одноразового кода секретным ключем пользователя в кодировке BASE64 без переводов строк>" | + | "sign": "<подпись строки одноразового кода секретным ключем пользователя в кодировке BASE64 без переводов строк>", |
+ | "sign_type": "<тип подписи (например "SHA256withRSA")>", | ||
+ | "cancel_public_key": "<публичный ключ отмены текущего ключа пользователя в кодировке Base64 без переводов строк>", | ||
+ | "cancel_public_key_sign": "<подпись текущим ключем публичного ключа отмены>" | ||
} | } | ||
Строка 28: | Строка 58: | ||
"status": 0 | "status": 0 | ||
} | } | ||
+ | |||
+ | === Запрос на подписание документа === | ||
+ | |||
+ | Для инициирования подписания документа в приложение необходимо передать (например, с помощью QR-кода) следующий URL: | ||
+ | <pre> | ||
+ | signdoc://<URL без схемы по которому можно получить содержимое документа для подписания> | ||
+ | </pre> | ||
+ | При получении данного URL, приложение подменяет схему на http и делает GET запрос по получившемуся URL, ожидая в теле ответе запрос на подписание в виде JSON. | ||
+ | |||
+ | Например, если исходный URL из QR кода будет вот таким: | ||
+ | <pre> | ||
+ | signdoc://client.site.ru/get_doc?id=TkhqUYuh | ||
+ | </pre> | ||
+ | тогда приложение будет пытаться получить документ для подписания по адресу | ||
+ | <pre> | ||
+ | http://client.site.ru/get_doc?id=TkhqUYuh | ||
+ | </pre> | ||
+ | |||
+ | При этом, документ может быть представлен в двух видах - персонифицированном и открытом виде. В персонифицированном виде данные документа шифруются публичным ключем пользователя, для которого этот документ предназначен. В открытом виде данные не шифруются и в документе отсутствуют атрибуты принадлежности документа конкретному пользователю. | ||
+ | |||
+ | ==== Персонифицированный запрос на подписание документа ==== | ||
+ | |||
+ | { | ||
+ | "type": "SIGN_REQUEST", | ||
+ | "site": "<идентификатор сайта клиента>", | ||
+ | "doc_id": "<внутренний идентификатор документа на сайте клиента>", | ||
+ | "template": "<шаблон для показа данных документа>", | ||
+ | "sign_url": "<URL на сайте клиента, на который следует отправить подпись данного документа>", | ||
+ | "user_key_id": "<идентификатор публичного ключа пользователя, которому предназначен данный документ>", | ||
+ | "data": "<данные документа, зашифрованные публичным ключем пользователя, для которого предназначен документ>" | ||
+ | } | ||
+ | |||
+ | ==== Публичный запрос на подписание документа ==== | ||
+ | |||
+ | { | ||
+ | "type": "SIGN_REQUEST", | ||
+ | "site": "<идентификатор сайта клиента>", | ||
+ | "doc_id": "<внутренний идентификатор документа на сайте клиента>", | ||
+ | "template": "<шаблон для показа данных документа>", | ||
+ | "sign_url": "<URL на сайте клиента, на который следует отправить подпись данного документа>", | ||
+ | "dec_data": "<данные документа в открытом виде>" | ||
+ | } | ||
+ | |||
+ | При этом следует учитывать что на такой запрос о подписании необходимо отправлять подпись документа вместе с публичным ключем. Т.к. при таком подписании не предусмотрена регистрация подписи пользователя. Т.е. подпись документа будет выглядеть следующим образом: | ||
+ | { | ||
+ | "type": "SIGN", | ||
+ | "site": "<идентификатор сайта клиента>", | ||
+ | "doc_id": "<внутренний идентификатор документа на сайте клиента>", | ||
+ | "sign": "<подпись документа в кодировке Base64 без переводов строк>", | ||
+ | "sign_type": "<тип подписи (например "SHA256withRSA")>", | ||
+ | "public_key": "<публичный ключ пользователя в кодировке Base64 без переводов строк>" | ||
+ | } | ||
+ | В этом случае идентификационные данные пользователя в читаемом формате необходимо получать либо из специальной сети доверия, либо размещать на сайте клиента позже с привязкой к подписи. | ||
+ | |||
+ | === Список URL API для сайта клиента === | ||
+ | |||
+ | # URL POST, по которому будет присылаться регистрация подписи | ||
+ | # URL GET, по которому будет выдаваться документ, требующий подписания | ||
+ | # URL POST, по которому будет отправляться подпись документа |
Текущая версия на 13:52, 26 марта 2015
Содержание |
Общее описание
В мобильном приложении встроена возможность взаимодействовать с сайтом клиента напрямую через URL в ссылках или QR-кодах. При этом приложению передается информация о прямых ссылках на сайт-клиент и взаимодействие происходит минуя прокси-сервера.
Криптография
Ключ пользователя представляет из себя пару RSA ключей размером не менее 2048 бит. Идентификатор ключа пользователя формируется через получение хэша SHA-256 от бинарного представления публичного ключа пользователя. Идентификатор представляется в кодировке BASE64 без переводов строк.
Подпись представляет собой двоичную ЭЦП "SHA256withRSA" (тип подписи передается на сайт в атрибуте "sign_type"), представленную в кодировке BASE64 без переводов строк.
Зашифрованные данные в случае, если их размер меньше 2048 бит (256 байт), шифруются публичным RSA ключем пользователя "как есть". Если данные размером больше чем 256 байт, то их шифрование происходит с помощью алгоритма AES со случайным ключем (256 бит). Причем, в этом случае в начале зашифрованных данных идет блок из 256 байт, зашифрованный открытым RSA ключем пользователя, который содержит: байты 0-31 (32 байта) - случайный AES ключ, байты 32-47 (16 байт) - случайный AES IV, байты 48-79 (32 байта) - CRC в виде хэша SHA256 от шифруемых данных (данных в открытом виде). Дальше содержаться сами данные, алгоритм шифрования которых "AES/CBC/PKCS5Padding". В конечном виде бинарные зашифрованные данные представляются в виде BASE64 без переводов строк.
В качестве строки для формирования электронной подписи документа используется
$doc['site'].":".$doc['doc_id'].":".$doc['dec_data'].":".$doc['template']
Ключ отмены (аннулирования)
"Ключ отмены" генерируется случайным образом одновременно с генерированием основного ключа. Ключ отмены служит для того, что-бы владелец мог объявить рабочий ключ скомпрометированным и не действующим. Для этого во всех пакетах регистрации публичного ключа присутствует два поля - cancel_public_key и cancel_public_key_sign. В первом содержится публичная часть ключа отмены. Во втором - подпись публичного ключа отмены основным ключем (привязка ключа отмены к основному ключу). В случае необходимости сообщить об отмене (аннулировании) ключа, пользователю необходимо любым из способов сформировать и отправить на все сайты, использующие его ключ, следующий пакет:
{ "type": "CANCEL", "user_key_id": "<идентификатор основного публичного ключа пользователя подлежащего отмене>", "cancel_time": "<момент отмены в формате UNIXTIME в таймзоне GMT>", "cancel_sign": "<подпись строки со временем отмены секретным ключем отмены пользователя в кодировке BASE64 без переводов строк>", "cancel_sign_type": "<тип подписи (например "SHA256withRSA")>" }
Запрос на регистрацию подписи на сайте клиента
Для инициирования процедуры регистрации подписи на сайте клиента в приложение необходимо передать (например, с помощью QR-кода) следующий URL:
signreg://<домен сайта-клиента>/<путь регистрации подписи на сайте клиента>?code=<одноразовый код для регистрации>&site=<идентификатор сайта клиента>
ВАЖНО!!! Т.к. одноразовый код подписывается приложением автоматически, для его вида существуют жесткие ограничения: одноразовый код должен состоять только из цифр и быть размером не более 16 символов.
URL по которому приложение будет передавать регистрацию подписи, составляется в виде:
http://<домен сайта-клиента>/<путь регистрации подписи на сайте клиента>
По этому URL будет выполнен POST запрос с передачей в нем следующего документа о регистрации подписи в виде JSON документа:
{ "type": "REGISTER", "site": "<идентификатор сайта клиента>", "code": "<одноразовый код для регистрации подписи>", "public_key": "<публичный ключ пользователя в кодировке Base64 без переводов строк>", "sign": "<подпись строки одноразового кода секретным ключем пользователя в кодировке BASE64 без переводов строк>", "sign_type": "<тип подписи (например "SHA256withRSA")>", "cancel_public_key": "<публичный ключ отмены текущего ключа пользователя в кодировке Base64 без переводов строк>", "cancel_public_key_sign": "<подпись текущим ключем публичного ключа отмены>" }
При удачной обработке URL должен вернуть JSON ответ со статусом 0:
{ "status": 0 }
Запрос на подписание документа
Для инициирования подписания документа в приложение необходимо передать (например, с помощью QR-кода) следующий URL:
signdoc://<URL без схемы по которому можно получить содержимое документа для подписания>
При получении данного URL, приложение подменяет схему на http и делает GET запрос по получившемуся URL, ожидая в теле ответе запрос на подписание в виде JSON.
Например, если исходный URL из QR кода будет вот таким:
signdoc://client.site.ru/get_doc?id=TkhqUYuh
тогда приложение будет пытаться получить документ для подписания по адресу
http://client.site.ru/get_doc?id=TkhqUYuh
При этом, документ может быть представлен в двух видах - персонифицированном и открытом виде. В персонифицированном виде данные документа шифруются публичным ключем пользователя, для которого этот документ предназначен. В открытом виде данные не шифруются и в документе отсутствуют атрибуты принадлежности документа конкретному пользователю.
Персонифицированный запрос на подписание документа
{ "type": "SIGN_REQUEST", "site": "<идентификатор сайта клиента>", "doc_id": "<внутренний идентификатор документа на сайте клиента>", "template": "<шаблон для показа данных документа>", "sign_url": "<URL на сайте клиента, на который следует отправить подпись данного документа>", "user_key_id": "<идентификатор публичного ключа пользователя, которому предназначен данный документ>", "data": "<данные документа, зашифрованные публичным ключем пользователя, для которого предназначен документ>" }
Публичный запрос на подписание документа
{ "type": "SIGN_REQUEST", "site": "<идентификатор сайта клиента>", "doc_id": "<внутренний идентификатор документа на сайте клиента>", "template": "<шаблон для показа данных документа>", "sign_url": "<URL на сайте клиента, на который следует отправить подпись данного документа>", "dec_data": "<данные документа в открытом виде>" }
При этом следует учитывать что на такой запрос о подписании необходимо отправлять подпись документа вместе с публичным ключем. Т.к. при таком подписании не предусмотрена регистрация подписи пользователя. Т.е. подпись документа будет выглядеть следующим образом:
{ "type": "SIGN", "site": "<идентификатор сайта клиента>", "doc_id": "<внутренний идентификатор документа на сайте клиента>", "sign": "<подпись документа в кодировке Base64 без переводов строк>", "sign_type": "<тип подписи (например "SHA256withRSA")>", "public_key": "<публичный ключ пользователя в кодировке Base64 без переводов строк>" }
В этом случае идентификационные данные пользователя в читаемом формате необходимо получать либо из специальной сети доверия, либо размещать на сайте клиента позже с привязкой к подписи.
Список URL API для сайта клиента
- URL POST, по которому будет присылаться регистрация подписи
- URL GET, по которому будет выдаваться документ, требующий подписания
- URL POST, по которому будет отправляться подпись документа