Я нашел слабое место моей схемы по сравнению со схемой Андрея.
Если кто-то случайно узнает владельза записи в Таблице результатов голосования, то голос может быть подделан без проблем, используя тот же Секрет Пользователя в Голосовании, который выборал пользователь.
Исправлю свою схему с использованием стандартной процедурой "подпись, шифровка", то есть подписываем все данные, потом все данные с подписью шифруем, как сделал Андрей.
Сам текст исправленной схемы:
Я опишу минимальную схему, которая, с моей точки зрения, обеспечивает тайность голосования и невозможность его подделки, в том смысле, что каждый проголосовавший сможет проверить свой голос. В конце я приведу некоторые дополнения, которые не сказываются на тайности голосования и невозможности его подделки, но делают схему более удобной в применении.
Предположения: у человека есть Логин (уникален в системе), секретный пароль (никогда не передается по телекоммуникационным сетям, знает его только пользователь, нужен для доступа к паре открытый-закрытый ключ), пара открытый-закрытый ключ (закрытый ключ используется для подписи, открытый ключ - для шифрования). Закрытый ключ известен только пользователю, открытый ключ - кому угодно. Открытые ключи передаются по каналам связи, закрытые ключи никогда не передаются по каналам связи. Пара открытый-закртый ключ выдается по паспорту, что обеспечивает однооднозначное (одно - 2 раза) соответствие между пользователями и парами ключей.
Голосование: вопрос, варианты ответов (конечное число, варианты определяются предварительно). Каждое голосование имеет Уникальный Серийный Номер Голосования. Уникальный Серийный Номер Голосования передается по каналам связи. Варианты ответов и их числовые представления известны всем. Они передаются по каналам связи.
Процесс голосования: 1. Пользователь решает принять участие в голосовании. 2. Голосующий подписывает Уникальный Серийный Номер Голосования своим закрытым ключом. 3. Голосующий выбирает вариант, за который он отдет свой голос. 4. Пользователь выбирает произвольное число, какое захочет, назовем его Секрет Пользователя в Голосовании. Секрет Пользователя в Голосовании НЕ передается по каналам связи в первозданном виде.
Составляем таблицу участвоваших в голосовании: 1. Логин (по нему мы можем выяснить все данные пользователя: ФИО, контакты, фото). 2. Подписанный закрытым ключом пользователя Уникальный Серийный Номер Голосования.
Эта таблица защищиает результаты голосования от изъятий и вложений. Если в этой таблице есть запись, что пользователь принял участие в голосовании, то и в следующей таблице должна быть запись, соответствующая пользователю.
Составляем таблицу результатов голосования: 1. Уникальный Серийный Номер Голосования. 2. Числовое Представление Варианта Ответа. 3. Секрет Пользователя в Голосовании, подписанный закрытым ключом пользвателя. Сам Секрет Пользователя в Голосовании в это поле не вносится. 4. Специальное Поле.
Столбцы 1,2 используются для подведения итогов голосования.
Столбецы 3,4 - используются для проверки самим пользователем правильности стобцов 1,2.
Специальное Поле - это подписанные закрытым ключом пользователя данные (Уникальный Серийный Номер Голосования, Числовое Представление Варианта Ответа, Логин, Секрет Пользователя в Голосовании), которые потом зашифрованны открытым ключом польвателя. Расшифровать его может только сам пользователь. Зашифрованное Специальное Поле передается по каналам связи.
Никакаие другие данные по голосованию не сохраняются.
После проведения голосования, любой человек может скачать результаты и подвести итоги голосования.
Поиск своей записи в голосовании: перебираем все строки. Та строка, поле 3. которой расподписалось в Секрет Пользователя в Голосовании с помощью открытого ключа, а поле 4. расшифровалось с помощью закрытого ключа, является строкой пользователя в голосовании, то есть пользователь расшифровывает и ищет свой логин. Ниже будет приведен способ делать это проще, не так затратно в смысле вычислений.
Обеспечение тайны голосования - есть. Единственное поле, которые может выдать пользователя по его подписи - это 3. Но, если у вас есть доступ только к открытым ключам пользователей и вы не знаете Секрет Пользователя в Голосовании, то каким бы открытым ключем вы не расподписывали поле 3., вы будете получать ничего не значащее для вас число. Никто не может расшифровать поле 4., кроме самого пользователя, так как только пользователь, знающий закрытый ключ, может расшифровать это поле.
Невозможность подделки голосования - есть. 1. Просто поменять поле 2. Числовое Представление Варианта Ответа. Тогда пользователь находит свою запись, видит, что она поменялась. Заявляет, что запись подделана. Пользователь расшифровывает Специальное Поле - только он знает закрытый ключ, Секрет Пользователя в Голосовании расподписывается, пользователь раскрывает закрытый ключ. Проверка: Факт, что пользователь смог расшифровать 4. доказывает, что это его запись, Секрет Пользователя в Голосовании из 3. совпадает с Секрет Пользователя в Голосовании из 4., Числовое Представление Варианта Ответа из 2. НЕ совпадает с Числовым Представлением Варианта Ответа из 4, закрытый ключ соответсвует открытому ключу. Так как пара ключей раскрыта, она переиздается для пользователя. 2. Попытка изменить поле 2. и поле 4. - меняем выбор пользователя и меняем соответственно поле 4. Это возможно сделать, так как поле 4. шифруется открытым ключем пользователя, который всем известен. НО: Из-за невозможности выяснить, кому принадлежит конкретная запись, становится невозможно выбрать логин, который записывается в поле 4.. Даже если с логином угадали, то туда надо вписать Секрет Пользователя в Голосовании такой же, как и в поле 3. Но подписать произвольный Секрет Пользователя в Голосовании может только сам пользователь.
Ниже описана модификация для быстрого поиска записи пользователя голосования:
Выдаем пользоватлю Уникальный Одноразовый Идентификатор Пользователя в Голосовании. Добавляем Уникальный Одноразовый Идентификатор Пользователя в Голосовании в таблицу результатов голосования и в Специальное Поле. Теперь пользователь может искать свою запись по Уникальный Одноразовый Идентификатор Пользователя в Голосовании.
Невозможно выдать один и тот же Уникальный Одноразовый Идентификатор Пользователя в Голосовании нескольким пользователям, так как иначе будет несколько записей в базе данных с одинаковыми Уникальный Одноразовый Идентификатор Пользователя в Голосовании, что легко проверяется, либо одна запись, Специальное Поле которой сможет расшифровать только один из пользователей.
Описанная выше схема работает при следующих условиях: 1. Никто не запоминает соответсвия Уникальный Одноразовый Идентификатор Пользователя в Голосовании <--> Логин в открытом виде. 2. Уникальный Одноразовый Идентификатор Пользователя в Голосовании могут получить только пользователи, прошедшие аутентификацию, то есть не существует Уникальный Одноразовый Идентификатор Пользователя в Голосовании, которые бы не соответствовали реальному пользователю системы.
Для дополнительного удобства пользователя (чтобы ему не пришлось запоминать Уникальный Одноразовый Идентификатор Пользователя в Голосовании), создаем следующую таблицу.
Таблица поиска: 1. Логин пользователя 2. Уникальный Серийный Номер Голосования 3. Уникальный Одноразовый Идентификатор Пользователя в Голосовании, зашифрованный открытым ключом пользователя.
|