![image](https://habrastorage.org/getpro/habr/post_images/034/6fb/33e/0346fb33e0de9e0289bcbacb19074c81.png)
На данный момент это решение готово и я хочу поделиться им с общественностью. Исходные коды распространяются под открытой лицензией (ссылки в конце статьи).
Итак, что-же я предлагаю…
Мобильное приложение, находящееся на смартфоне пользователя, обеспечивает всю базовую криптографию — создание ключей, их хранение и подписание документов. Документы представляют собой набор данных и шаблон для их отображения. Сейчас доступны два типа шаблонов: простой список и HTML шаблон.
Пользователи идентифицируются по хэшу их публичного ключа. Сайты, запрашивающие подписание каких-либо документов (далее — «клиенты») идентифицируются по их символьному идентификатору (в общем случае — по домену сайта). В системе так-же присутствует промежуточный элемент, который обеспечивает передачу пакетов между пользователем и клиентами — прокси сервер. Сразу хочу заметить, что на прокси-серверах не доступна информация о подписываемых документах, т.к. она шифруется открытым ключем пользователя.
Порядок работы
Естественно, что-бы сайт клиента мог отправить документ на подписание определенному пользователю, ему нужно сначала каким-то образом получить открытый ключ пользователя и привязать его к своей внутренней логике (например, к логину пользователя). Для этого предназначена процедура «Регистрации подписи». Заключается она в следующем:
— сайт выдает пользователю пару строк: свой идентификатор (обычно домен) и одноразовый код;
— пользователь вводит эти данные в мобильное приложение которое формирует пакет со следующими данными: своим открытым ключем и одноразовым кодом, который им подписан. И отправляет этот пакет на прокси сервер;
— сайт клиента получает от прокси сервера этот пакет и привязывает публичный ключ к своей логике.
После этого, в случае необходимости подписания документа на сайте:
— клиент формирует документ на подписание (включая внутренний идентификатор документа), шифрует данные документа открытым ключем пользователя, устанавливает для него идентификатор пользователя по его публичному ключу и отправляет на прокси;
— пользователь, когда ему будет удобно, проверяет наличие новых документов на подпись;
— при получении такого документа пользователь расшифровывает его данные и формирует из них, шаблона и некоторых других атрибутов документа его подпись;
— полученную подпись он отправляет на прокси сервер вместе с идентификатором клиента и внутренним номером документа. Сами данные документа не отправляются (они сохранены у клиента);
— клиент получает подпись, по внутреннему идентификатору извлекает оригинальные данные документа, проверяет подпись и, если она корректна, сохраняет ее для дальнейших действий.
На этом цикл заканчивается.
Итоги и перспективы
Конечно, я могу признать что система не идеальна. Но это первый вариант и, что самое важное, он есть и он работает. Так-же важно то, что его можно использовать не только для целей нашего проекта, которые связаны с реализацией голосований. Его можно использовать, например, для обеспечения двухфакторной авторизации. Или для защиты критичных действий пользователя типа изменения пароля или привязанного к логину e-mail (такой опциональный функционал уже внедряется на одном из популярных сайтов). Это базовый инструмент и на его основе можно построить все что угодно — дело ограничено лишь нашей фантазией. :)
В планах много доработок. Мобильный клиент сейчас имеет самый минимальный функционал — только регистрацию на сайте и подписание или отказ в подписании документа. В планах на следующую версию — запоминание всех документов пользователя в мобильном приложении, реализация возможности связи с сайтами клиентов напрямую (без использования прокси серверов), если они поддерживают эту возможность, а так-же создание версии для iOS (сейчас доступна версия мобильного приложения только для Android).
Проект полностью открытый и мы приветствуем как собственные разработки на основе нашего кода, так и помощь нашему проекту (например, нам-бы очень не помешала помощь в портировании приложения на iOS). :)
Ну и ссылки:
Мобильное приложение в Google Play Market: GPLVote Sign Doc
Исходный код мобильного приложения на GitHub
Тестовый сайт клиента для тестирования мобильного приложения
Perl модуль GPLVote::SignDoc::Client, облегчающий прикрутку нужного функционала к сайтам клиентов
Исходный код тестового клиента на GitHub (Perl)