Что-то я запутался в топике. Много обсуждений, но несколько не верные. Может мне только кажеться, но свои мысли изложу.
Есть несколько требований к системе и есть несколько условий, которые должны выполнятся.
Требования:
Голосования могут быть открытыми (условно) и анонимными (полностью).
Что это знаничит - открытые - это когда у любого голоса есть возможность идентифицировать кто его оставил. Это информация может быть частично закрытой - т.е. не покидать сервера, например, но в таком случае сохраняется возможность извлеч информацию из сервера.
Второй вариант - анонимное голосование. Когда результат голоса есть, но кто как голосовал установить нельзя. Т.е. даже в рамках сервера не имеется информации о том, кому данный голос в действительности принадлежал.
Человек должен иметь возможность проверить, что его результаты голосования учтены и были правильно посчитаны. Так же человек в любом случае должен получить оповещение в системе, если его голос где либо голосовал (что бы выявлялись случаи, когда за человека проголосовали, а он об этом и не знал).
Постулаты:
Кто-то все равно считает голоса. А значит имеет доступ к части информации. Подразумевается, что счетчиком голосов будет компьютер, но тут есть несколько вопросов - что компьютер имеет доступ к результатам голосования, что может быть опасно - так как программу можно раскурочить и получить доступ к результатам (если они были не полностью анонимными), а если были анонимными - то и фальсифицировать их (накрутить).
В данном месте я вижу, что у каждого голосования должны быть ответственные лица, которые отвечают за сохранность системы результатов голосования). Т.е. в данном случае накладываем требование, что для подсчета голосов требуется участие некоторого комитета, которые предоставляют свои ключи реализации подсчета голосов.
Вариант, когда каждый участник голосования входит в подобный коммитет не пройдет – слишком много людей. Я позже изложу, как в моем понимании такая система работать должна (с комитетом).
Т.е. еще раз, самое главное – кто-то должен считать голоса.
Подсчет голосов подразумевает не только предоставление статистики, но и возможность повторного пересчета или поднятие истории, откуда взялся конкретный голос (если это не анонимный голос, но по нему у меня есть несолько идей отдельных).
Что означает анонимный голос? Что есть результат (выбор одной из опций голосования) но невозможно определить, который из пользователей системы голосовал этим голосом.
При этом должно учитываться, кто принимал участие в голосовании. Т.е. информация о том, кто голосовал в системе есть, а вот как голосовали – нет. Это необходимо для того, что бы не появлялись «левые» голоса.
Как это может работать:
Состав системы будет состоять из программного обеспечения на локальном компьютере человека и распределенной сети серверов.
В случае открытого голосования (т.е. когда каждый голос ассоциирован с конкретным человеком) все достаточно просто.
1) Голосование создается Группой заинтересованных лиц (комитетом) и на него назначаются ответственные лица, отвечающие за подсчет голосов. Так же определяются размер кворума ответственных для подсчета голосов (например для подсчета голосов требуется не менее 70% ответственных).
2) Голосование доступно для конечных пользователей и они производят голосование. При этом происходит следующее. Результат голосования подписывается личной подписью голосовавшего. Далее подписанный результат голосования шифруется ключами ответственных за подсчет, таким образом только ответственные могут расшифровать и просмотреть результат голосования. При шифровании учитываем, что сообщение должно расшифровываться кворумом ответственных, т.е. не всеми, не одним, а определенным процентом. Это можно сделать, например, путем внесения избыточности в подписанный результат голосования (до 100% минус процент кворума), разбиванием полученного блока по количеству ответственных и шифрованием полученных блоков по отдельности ключами ответственных за подсчет. Так же данное сообщение шифруется дополнительно подписью пользователя. Т.е. пользователь может так же расшифровать свое сообщение, не только коммитет.
3) Ключи отправляются на сервера и там хранятся до подсчета голосов. В локальной программе у пользователя статус голосования – голос отправлен на сервер. Естественно, сервер проверяет, может данный человек принимать голосование или нет, сверяясь со списком голосования. «Левые» голоса отбрасываются и голосуещему доставляется оповещение.
4) Для подсчета голосов ответственные собираются вместе и предоставляют серверу свои ключи для расшифровки. Для каждого голосования вполне могут быть использованы одноразовые ключи, которые генерятся для каждого голосования для каждого ответственного. Требование к серверу – он должен быть не скомпроментирован. Т.е. мы ему доверяем. С использованием данных ключей производится расшифровка результатов голосования и подствет голосов.
5) Результат голосования доводится до каждого пользователя – пользователь видит может посмотреть сколько голосов было отданно и был ли учтен его голос. Для этого сервер может по запросу пользователя вернуть информацию о том, что голос учтен или нет при подсчете и какой он был (т.к. он был зашифрован ключем голосующего, то возвращаем ему его запись, а он ее может дешифровать и сравнить).
В случае анонимного голосования немного все сложнее и есть потенциальные уязвимости для результата голосования.
При анонимном голосовании можно поступить так:
1) Первый шаг аналогичен открытому голосованию, т.е. формируется комитет, ответственные и определяется размер кворума.
2) При генерации голосования (подготовке к голосованию) ответственные предоставляют свои ключи (должны предоставить все), на сервере генерируются одноразовые идентификаторы в количестве возможных голосующих. Каждый одноразовый идентификатор комбинируется с идентификатором голосования, датой генерации (при необходимости – другой информации, например идентифицирующая информация сервера, на котором производилась генерация идентификаторов) и подписывается подписями всех отвественных. Это позволит исключить появление дополнительных ключей в будущем. Сгенерированная информация заносится в базу и формирует собой пул свободных идентификаторов.
3) Голосующий формирует у себя запрос на получение уникального идентификатора по голосованию. В этом запросе информация о голосовании подписывается своей подписью и отправляется на сервер. Сервер в ответ выделяет из пула свободных идентификаторов один, перемещает данную запись в пул использованных идентификаторов, в базу голосования добавляет, что голосующий получил уникальный идентификатор (но сам идентификатор не указывается, только факт получения), а пользователю возращается идентифкар для голосования. Таким образом нет связи между голосующим и конкретным идентификатором, но есть запись, что глосующий хотел принять участие в голосовании. Процедура подобна выдаче бланка бюлютеня при голосовании. Сервер может для безопасности зашифровать подписанный идентификатор голосования ключем пользователя, т.к. он известен серверу, а пользователь у себя его расшифрует. Пользователю может по одному голосованию получить только один идентификатор.
4) Голосующий комбинирует одноразовый идентификатор с результатами голосования и шифрует сообщение ключами ответственных аналогично пункта 2 для открытого голосования, результат должен содержать уникальный идентификатор, сгенерированный голосующим
5) Результаты шифрования отправляются на сервер и там используются для подсчета голосов.
6) Как и в открытом голосовании ответственные собираются и производится подсчет голосов. Ответственные предоставляют свои ключи серверю, сервер с использованием ключей ответственных дешифрует поступившие голоса и проверяет для каждого сообщения правильность подписей на идентификаторе. Так же каждый учтенный голос проверяется, что бы идентификатор использовался один раз.
7) Для проверки результатов голосования голосующие обращаются к серверу и получают список всех анонимных идентификаторов и ассоциированные с ними уникальные идентификаторы, которые генерировались пользователями, а так же результаты голосования (выбор голосующего) по данному идентификатору. Сверяя идентификаторы с тем, что использовались пользователем, голосующий имеет информацию, был ли принят его голос и правильно ли учтены его результаты. Т.к. информация о связи идентификаторов с конкретным пользователем отсутсвует, то данная информация не компроментирует пользователя.
В смешаном голосовании все так же, комбинируются оба метода, только результат можно выводить в виде статистики, сколько было открытых голосов, сколько закрытых и т.д.
Можно предусмотреть возврат идентификатора в пул - идентификатор пометится как использованный и не будет приниматься к участию в голосовании (это если пользователь захотел голосовать открыто).
Нужны проверки на двойное голосование одним пользователем (анонимное голосование должно иметь преимущество).
Возможные проблемы – уход с сервера одноразовых идентификаторов при анонимном голосовании может решаться только оповещением голосующего, что он принимал участие в голосовании, когда у него фактически не было запроса на сервер. Т.к. все голосующие известны, то нужно всех оповещать о прошедшем голосовании и клиент у голосующего может сообщать, если голос его учавствовал в голосовании, но фактически запроса пользователем не посылалось. Само по себе это не преступление (пользователь мог переустановить программу и удалить у себя запросы на голосование), но может служить поводом к расследованию.
Сервис вполне может ложиться на распределенную систему.
Знаю, много написал, но коротко не умею.
Прошу оценить идею.