Этот пост — ответ на habrahabr.ru/post/244753/
Для повышения доверия и прозрачности к РОИ, можно применить достаточно простое решение, описанное в этом посте. Когда пользователь голосует за, против, или отзывает свой голос за какую либо инициативу, необходимо чтобы РОИ генерировал специальный проверочный код, но не содержащий личной информации пользователя. Список таких кодов должен быть доступен в общем пользовании. Таким образом, каждый мог бы проверить результат учета своего голосования в публичном доступе. Данное техническое решение является простым, дает возможность контроля подсчета голосов до некоторой степени и, таким образом, повышает доверие граждан к РОИ.
Предлагаемый протокол действий.
Для начала, РОИ генерирует 2048 битный RSA ключ-пару (SK, PK), где SK-секретный ключ и PK-публичный ключ. Публичный ключ публикуется в открытом доступе, а секретный хранится и используется только на сервере РОИ. Таких ключей может быть один для всего РОИ или много разных для разных инициатив. Например, можно генерировать свой отдельный ключ для каждой инициативы. Или обновлять ключ для всего ROI время от времени. Для идентификации ключа будем использовать понятие «версия ключа» (или индекс, номер ключа). Дополнительно, но совсем не обязательно для первой версии системы, РОИ может публиковать сертификат ключа.
Структура и генерация кодов, которые должны быть в публичном доступе.
1. При голосовании пользователем, ROI формирует следующий вектор V, длинною 49 байт:
Версия (номер) ключа: 4 байта
Номер инициативы: 4 байта
Время события (UTC время): 8 байт
Тип события: 1 байт (ЗА, ПРОТИВ, ОТЗЫВ)
Хеш проголосовавшего пользователя, вычисляемый как
H = SHA256(SK; СНИЛС; Номер Инициативы): 32 байта.
2. Далее, РОИ использует соответствущий секретный RSA ключ SK для того, чтобы получить вторую часть кода — цифровую подпись:
S = RSA_Encrypt(SK; V) – результат будет 256 байт.
3. Пара (V; S) высылается электронной почтой проголосовавшему пользователю, а также помещается в публичный доступ (например, в текстовом PEM формате).
Плюсы:
• Любой человек по открытому списку пар {V;S} может подсчитать общее число голосов для выбранной инициативы, предварительно верифицировав каждое значение Vx, используя публичный ключ РОИ следующим образом: RSA_Decrypt(PK; Sx) должно быть в точности равно значению Vx.
• Любой по списку {V;S} может найти свой код голосования, так как он должен быть послан по электронной почте пользователю сразу после голосования. Если код не найден в общем списке, пользователь может предъявить свою пару (Vx, Sx) как доказательство неучтенного голоса.
• Третьи лица не смогут говорить об неучтенном голосе Vx без предоставления соответствующей пары-подписи Sx, так как для этого необходимо знать секретный ключ РОИ. Таким образом, РОИ защищено от необоснованных претензий такого рода.
• Поле H добавлено в строку V для того, чтобы однозначно идентифицировать действия одного и того же пользователя в рамках выбранной инициативы. Например, последовательность ЗА-ОТМЕНА-ПРОТИВ должна быть привязана к конкретному пользователю, чтобы можно было отследить эту последовательность в списке событий {V;S}. При этом сам СНИЛС пользователя является недоступным, так как в хеш, который генерируется на сервере РОИ, включен секретный ключ РОИ. По хешу невозможно узнать ни секретный ключ, ни СНИЛС человека. И даже если СНИЛС известен, то невозможно узнать секретный ключ РОИ по хешу. Также, невозможно проверить каким образом голосовал тот или иной человек, зная его СНИЛС, так как связь между СНИЛС и H не является публичной информацией, она известна только проголосовавшему, как и сам результат голосования – эта информация и сейчас высылается пользователю по электронной почте. Таким образом, данная конструкция не изменяет нынешний уровень безопасности личной информации (как голосовал человек), а также нет утечки информации по СНИЛС или секретному ключу РОИ.
• При предъявлении потерянного голоса (Vx, Sx) конкретным пользователем в публичный доступ, создается связующая пара между голосом и конкретным человеком, и тогда всем становится ясно как этот конкретный человек голосовал. Но и сейчас ситуация похожая – если я голосовал а мой голос не был учтен, то я, заявляя об этом, выдаю публично информацию о том как я проголосовал. Однако, плюс в том, что потерянный голос (Vx, Sx) и, таким образом, претензия к ROI, может быть передан в публичное пространство анонимно, не выдавая при этом связь с конкретным пользователем.
Минусы:
• Невозможно отследить сценарий, в котором РОИ может добавлять голоса ЗА или ПРОТИВ для несуществующих СНИЛС. Но этот сценарий возможен и сейчас.
Техническая реализация:
Для реализации идеи, ROI может установить OpenSSL (открытая и бесплатная криптографическая библиотека, широко используемая во многих системах а также при установления зашифрованных каналов в IP соединениях, в браузерах и многих других приложениях), и использовать ее из своих скриптов для всех вышеперечисленных операций: генерация RSA ключа, шифрование RSA и хеширование SHA256. Генерация ключа – медленная операция, но редкая (один раз или при открытии новой инициативы). Шифрование секретным ключем и хеширование – быстрые операции. OpenSSL можно использовать как из коммандной строки или скрипта, так и из различных компилируемых языков программирования, таких как C/C++. Реализация не требует никаких инфраструктурных или других сложных шагов, и вполне может уложиться в несколько строк скрипта или кода.
Автор: almax