Только-что закончил процедуру тайного голосования. Весьма и весьма специфическая штука.
Попробую здесь описать ее нюансы и особенности реализации.
В процедуре тайного голосования нам нужно формировать 2 списка и записывать на сервере зашифрованные данные пользователя.
Списки:
1. Список проголосовавших. В него включается ссылка на пользователя и его подпись данных в которых нет упоминаний сделанного выбора.
2. Список голосов. Здесь для определенного голосования записывается одноразовый код пользователя и его выбор. По одноразовому коду пользователь сможет определить правильно-ли учелся его голос.
Данные пользователя:
1. Записывается, в зашифрованном ключем пользователя виде, одноразовый идентификатор из списка голосов.
Ради оптимальности я реализовал сохранение зашифрованного одноразового кода пользователя в его подписи об участии в голосовании в списке проголосовавших.
Далее начинаются интересные вещи. Мы подходим к технической реализации анонимности на уровне страницы и форм.
На этом уровне анонимность обеспечивается тем, что данные для списка проголосовавших и данные для списка голосов идут разными запросами, которые, в принципе, связать можно только по времени (а время, по крайней мере в списке голосов, НЕ записывается).
Здесь есть одна небольшая потенциальная возможность для злоумышленников подделать результаты голосования. Т.к. анонимные данные отправляются без привязки к пользователю, эти данные может отправить любой. И, теоретически, если запрос злоумышленника попадет между отправкой данных для списка голосовавших и анонимными данными обычного пользователя, тогда этот поддельный голос может попасть в список голосов.
Что-бы как-то защититься от такой атаки, при добавлении анонимных данных я проверяю что подписей в списке проголосовавших меньше чем записей в списке голосов.
Кроме того, при обнаружении обратной ситуации (когда идет атака), я выдаю соответствующее предупреждение пользователям и отправляю на свою почту (можно будет поменять на общую) предупреждение с IP злоумышленника.
В принципе, я так подумал, что принятые мною меры, как минимум, блокируют голосование при такой атаке. Т.е. злоумышленник сможет таким образом добавить лишь один поддельный голос. Т.е. подделать голосование злоумышленник не сможет, но заблокировать его, при желании, вполне.
Возможно, в будущем, можно будет сделать более интеллектуальный анализ такой атаки и автоматическую блокировку IP злоумышленника.