В общем, как-то мы застряли.
Я решил пойти с другой стороны - сначала обеспечить пользователей удобным средством для подписания любых документов. Кроме того, что мы используем его в своей системе, мы можем предлагать его и другим сервисам. Возможно, некоторым и не бесплатно.
Итак... Я подумал, что взять за базовое устройство мобильный телефон (коммуникатор) - это хорошая идея. Де-факто они есть почти у 100% населения. Кроме того, все более-менее умеют пользоваться приложениями на них.
Предлагаемая мною схема состоит из трех систем:
1. Мобильное приложение пользователя. Позволяет удобным образом получать, просматривать и подписывать документы;
2. Сервис, который отправляет пользователю документы на подписание и получает от него электронную подпись документа;
3. Среда передачи документов - системные сервера (прокси-сервера), с которыми взаимодействуют пользователи и клиенты и через которую идет трафик. Использование таких серверов не обязательно если будет найден другой способ передачи (например p2p сеть).
Т.к. клиенту необходимо отправлять документы конкретному пользователю, необходима какая-то идентификация пользователей. Я решил что лучшим способом будет идентификация по открытому ключу. Она наиболее естественна и не привязана к посторонним атрибутам. Когда пользователь отправляем на прокси сервера запрос на получение своих документов, он отправляет и свой публичный ключ вместе с подписью данного запроса. Прокси сервер проверяет подпись и если она верна, отдает пользователю его документы. Данный механизм необходим для избежания спам-запросов, а не для безопасности. Т.к. все данные документов шифруются открытым ключем пользователя, даже если документы пользователя скачает кто-то посторонний, он не сможет расшифровать данные.
Идентифицировать клиентов проще. Для этого мы используем "домен" сервиса. Он может представлять из себя как реальный домен, так и некое условное обозначение. Главное что-бы не было их дублирования в системе. Но т.к. изначально клиенты будут подключаться к системе вручную, эта проблема сейчас не акутальна.
Т.к. клиенту для отправки документа пользователю нужен его публичный ключ, необходима какая-то процедура, которая будет этот ключ ему передавать.
Я предлагаю вот такую процедуру:
1. Пользователь регистрируется на сайте клиента обычным образом и входит под своим логином.
2. На сайте будет кнопка "Привязать электронную подпись", по нажатию на которую сайт клиента выдаст пользователю "название сайта" и "одноразовый код". При этом, клиентский софт должен запомнить соответствие одноразового кода конкретному пользователю сайта (конкретному логину).
3. Пользователь запускает мобильное приложение и выбирает пункт "Регистрация на сайте". Вводит в поля полученные на сайте клиента данные и делает отправку "запроса на регистрацию". Этот запрос отправляется с подписанием с помощью ЭЦП, одноразового кода, полученного на этапе 2 и публичным ключем пользователя.
4. Клиент, получив с прокси сервера документ "запрос на регистрацию", проверяет ЭЦП кода с помощью публичного ключа вложенного в этот документ и, если все нормально, привязывает данный публичный ключ к пользователю, которого находит по одноразовому коду (связь с которым сохранена ПО клиента на шаге 3).
После этого получается что пользователю на сайте клиента соответствует определенный публичный ключ пользователя.
Процедура подписание документа следующая:
1. Сайт клиента на определенные действия пользователя, требующие подписания, создает специальный "запрос на подписание". В этом запросе будет передаваться: название сайта, внутренний идентификатор документа, хэш публичного ключа пользователя (как идентификатор ключа для более удобного поиска); данные документа, зашифрованные публичным ключем пользователя; шаблон для показа данных документа.
2. Далее этот документ отправляется клиентом на прокси сервер (с авторизацией по логину и паролю, который выдается клиенту на этапе ручной регистрации);
3. Пользователь нажимает на мобильном приложении кнопку "Проверить новые документы" и по идентификатору ключа скачивает новые документы с прокси-сервера.
4. Во всех скаченных документах расшифровываются данные документа и документ выдается пользователю в форме на подписание.
5. Если пользователь выбирает "Подписать", то формируется ЭЦП в которую входят: сайт документа, идентификатор документа, данные документа, шаблон документа. Сразу замечу, извлечь данные из подписи невозможно.
6. Документ "Подпись" отправляется на прокси сервер. В этот документ входят: сайт документа, идентификатор документа, подпись документа.
7. Клиент получает документы типа "Подпись" с прокси сервера, по идентификатору документа находит нужный документ, проверяет корректность подписи и, если она правильная, сохраняет ЭЦП в документе и помечает его как "подписанный".
8. После обработки подписи, клиент формирует специальный документ "подтверждение обработки подписи" и отправляет его пользователю.
9. Пользователь, получив документ о подтверждении обработки подписи, помечает локальную копию как "обработано".
В данный момент готового мобильное приложение Android, доступное пока по урл
http://ru.gplvote.org/signdoc.apkСсылка для тестирования мобильного приложения в Google Play:
https://play.google.com/store/apps/deta ... te.signdocИсходный код мобильного приложения:
https://github.com/UncleAndy/sign_docPerl модуль для клиентов:
http://search.cpan.org/~uncleandy/GPLVo ... /Client.pmТестовый сайт клиента:
http://client_signdoc.gplvote.org/Исходный код тестового сайта:
https://github.com/UncleAndy/sign_doc_client