разбор

Мэрия (случайно?) позволила расшифровать голоса на выборах в Мосгордуму. Мы это сделали и нашли кое-что странное Вы тоже можете попробовать

Источник: Meduza
Андрей Никеричев / Агентство городских новостей «Москва»

Это специальный «электронный» участок № 5003. В урнах лежат распечатанные транзакции блокчейна (в том числе зашифрованные голоса избирателей). Это дополнительная страховка от фальсификаций

Андрей Никеричев / Агентство городских новостей «Москва»

8 сентября 2019 года в трех округах Москвы прошел эксперимент по интернет-голосованию на выборах депутатов Мосгордумы. В одном случае его результаты оказались определяющими: в 30-м округе Роман Юнеман выиграл очное голосование, но уступил Маргарите Русецкой в дистанционном. Теперь он требует пересмотреть результаты. Организаторы эксперимента опубликовали результаты выборов, но не предоставили доступ к исходным данным. «Медуза» добыла секретный ключ, расшифровала все голоса избирателей и восстановила ход голосования.

Мэрия опубликовала зашифрованные голоса избирателей

Во время голосования департамент информационных технологий мэрии Москвы каждые полчаса выкладывал на специальном сайте сводные анонимные данные с зашифрованными голосами избирателей. Для каждого голоса там были указаны:

  • номер избирательного округа (1, 10 или 30);
  • номер блока в блокчейне, куда была записана транзакция с голосом;
  • время формирования этого блока;
  • зашифрованный выбор избирателя.

И (случайно?) оставила доступ к секретному ключу, который нужен для расшифровки голосов

После окончания голосования и публикации итогового CSV-файла с 9810 голосами избирателей приватный ключ был восстановлен из нескольких частей, заранее переданных доверенным лицам. Этот приватный ключ был записан в блокчейн. «Медуза» сумела найти нужный блок и транзакцию с приватным ключом через веб-интерфейс и скопировать данные до тех пор, пока доступ к блокчейну не был закрыт.

Обновление. В мэрии утверждают, что специально опубликовали приватный ключ. Но, если они намеренно предоставили наблюдателям доступ к приватному ключу, непонятно зачем через несколько часов нужно было закрывать доступ к веб-интерфейсу блокчейна.

Мы смогли расшифровать голоса избирателей

Для успешной расшифровки сообщений, зашифрованных по схеме Эль-Гамаля, кроме секретного ключа нам нужно было узнать один из компонентов открытого ключа — его модуль.

Чтобы его узнать, мы попросили научного редактора «Медузы» Александра Ершова, который голосовал через интернет, предоставить HTML-страницу своего бюллетеня. Там прописан публичный ключ, с помощью которого шифровался голос избирателя (в том числе необходимый нам модуль).

Если вы попытаетесь самостоятельно расшифровать голоса, учтите, что каждому кандидату на выборах был присвоен свой номер. Перед шифрованием в браузере пользователя этот номер возводился в квадрат. Поэтому, чтобы получить оригинальное значение, надо извлечь из расшифрованного числа квадратный корень.

И выяснили, за кого голосовал наш коллега

Александр Ершов записал процесс интернет-голосования в HAR-файл. Он позволяет сохранить весь входящий и исходящий трафик при посещении веб-сайта или взаимодействии пользователя с веб-приложением. Мы нашли в этом архиве зашифрованный голос — дальше все было просто.

Записать процесс своего интернет-голосования совсем не сложно — не нужно даже ставить специальные программы. Встроенные инструменты для записи веб-трафика в HAR-файлы есть в браузерах Google Chrome, Mozilla Firefox, Safari и даже Microsoft Edge.

Если временная публикация приватного ключа была организована преднамеренно, то теоретически руководители, заставлявшие своих работников проголосовать определенным образом, могли выяснить, как распорядились своим голосом их сотрудники.

Данные интернет-голосования выглядят странно

Официальные результаты эксперимента, подведенные участковыми избирательными комиссиями № 5001, № 5002 и № 5003, полностью совпадают с расшифрованными нами голосами избирателей. Без доступа к блокчейну мы, правда, не можем проверить число выданных избирателям бюллетеней.

Но чтобы заметить странности, можно даже ничего не расшифровывать. Достаточно разбить весь день голосования на отрезки по 5 минут и сгруппировать попавшие туда блоки с голосами избирателей.

Двенадцать часов, отведенные на интернет-голосование, оказались разбиты на неравные диапазоны. Там были и три часа, в течение которых голоса избирателей вообще не записывались в блокчейн, и час, когда была сгенерирована половина всех блоков с голосами (правда очень мелких — в 1-3 транзакции), и 5 минут, за которые в блокчейне оказались почти 1400 голосов (14% от общего числа).

  • С 08:02:58 до 09:26:04 были сформированы 53 блока (#668—#2046) с 3308 голосами избирателей; шаг между блоками (группами блоков) составлял около 2 минут.
  • Произошел первый сбой продолжительностью 54 минуты.
  • В 10:20:12 был сформирован один (#2525) с 35 голосами.
  • Произошел второй сбой продолжительностью 48 минут.
  • С 11:08:22 по 11:19:08 в блокчейн были записаны 7 блоков (#2651—#2818) с 92 голосами; шаг составлял 2 минуты.
  • Был объявлен перерыв, длившийся 1 час 10 минут.
  • С 12:29:18 до 13:08:18 были записаны 25 блоков (#2956—#3516) с 1189 голосами; шаг составлял 2 минуты.
  • С 13:10:28 до 14:13:46 были сформированы 328 блоков (#3541—#4686) с 612 голосами; шаг между блоками составлял несколько секунд, а между группами блоков — от 2 до 11 минут.
  • С 14:16:20 до 14:20:44 был записан 31 блок (#4731—#4804) с 1362 голосами; шаг составлял десятки секунд.
  • С 14:21:02 до 15:22:48 было сформирован 76 блоков (#4809—#5530) с голосами 1092 избирателей; шаг составлял окого 1 минуты.
  • С 15:24:48 до 20:00:44 были записаны 142 блока (#5544—#7168) с 2119 голосами избирателей; шаг вновь составлял около 2 минут.
  • В 20:15:28 был записан последний блок (#7190) с одним голосом.

Но, кажется, это следы технических проблем, а не вбросов

А вот это мы можем показать только благодаря расшифрованным голосам. Продемонстрируем распределение голосов у трех принципиальных соперников — независимого кандидата Романа Юнемана, провластного кандидата Маргариты Русецкой, а также кандидата от «Умного голосования» и КПРФ Владислава Жуковского.

Хотя есть и странность: распределение голосов за провластных и независимых кандидатов

Избиратели, выбиравшие провластных кандидатов, во всех трех округах заметно чаще голосовали утром (в первые полтора часа, до первого сбоя), чем избиратели независимых кандидатов.

Мы не знаем, можно ли с помощью этих данных зафиксировать принудительное голосование и определить его вклад.

Мы поминутно восстановили ход интернет-голосования

Это оказалось возможным благодаря использованию блокчейна. Мы точно знаем, что каждый голос, оказавшийся в определенном блоке не мог быть отдан позже времени записи этого блока в блокчейн. Разработчики московской системы интернет-выборов обещали случайным образом генерировать задержку для каждого бюллетеня перед записью в блокчейн. Возможно, она помогает только перемешивать голоса внутри блоков: голос Александра Ершова оказался в первом же блоке, сформированном после заполнения бюллетеня.

Посмотрите на реконструкцию противостояния Романа Юнемана и Маргариты Русецкой. Если допустить, что нам заранее известны результаты обычного «бумажного» голосования, то можно пошагово увидеть, как постепенно тает преимущество Юнемана в 581 голос.

А теперь делимся данными для исследователей

Вы можете скачать:

Не забудьте написать нам, если вы найдете в этих данных что-нибудь интересное.

Денис Дмитриев, Султан Сулейманов

Magic link? Это волшебная ссылка: она открывает лайт-версию материала. Ее можно отправить тому, у кого «Медуза» заблокирована, — и все откроется! Будьте осторожны: «Медуза» в РФ — «нежелательная» организация. Не посылайте наши статьи людям, которым вы не доверяете.