Архив 4 июля 2020

По мотивам очередного выступления

В эту субботу в очередной раз собрались обсуждать электронные выборы, и в этот раз ступора уже не было – то ли Шевяков не курил в камеру, то ли действительно надо привыкать к “публичным” выступлениям в Зуме :) Полную запись можно посмотреть на ютубе, а тут – перескажу свои основные тезисы.

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

Начну с того, что тайна голосования, которая волнует довольно многих избирателей и экспертов, действительно держалась на честном слове ДИТа. Это сложно назвать виной разработчиков и эксплуатантов системы – так уж получилось, что занимается этим ровно одно ведомство, а надо разделять систему как минимум на две части – чуть дальше станет понятно, почему, но Александр Исавнин действительно много раз задавал вопрос об этом, а ответов лучше, чем “поверьте нам на слово” техническая рабочая группа так и не получила. Опять же, отмечу, вслед за Олегом, что фактов нарушения тайны голосования пока никто не зафиксировал.

С другой стороны – некоторые технические меры для защиты тайны голосования были приняты. Да, при изучении кода системы заметно, что авторы попытались реализовать вариант хорошо известного “протокола двух агентств“, который защищает тайну голосования, и в принципе система позволяет разнести авторизацию пользователя и собственно голосование по разным ведомствам, что критично для этого семейства протоколов. Это в целом довольно положительно характеризует разработчиков системы – как минимум обращение к известным протоколам позволяет избавиться от всевозможных неожиданностей.

Чуть подробнее опишу протокол голосования – при этом постараюсь изложить это все максимально упрощенно. К сожалению, в Википедии описан похожий, но отличающийся протокол, а “Прикладная криптография” Шнайера есть под рукой далеко не у всех – хотя протокол, похожий на ДИТовский, там описан под названием “Голосование с двумя Центральными комиссиями”. Основаны все эти протоколы на криптографии с открытым ключом – здесь знать о ней надо лишь то, что используется пара из открытого и закрытого ключа, таких, что сообщение, зашифрованное открытым ключом, можно расшифровать только с помощью закрытого, и наоборот – если сообщение зашифровано закрытым ключом, то оно расшифровывается открытым. Закрытый ключ обычно держится в секрете, а открытый доступен всем.

Итак, для начала – подготовка к голосованию, которая с точки зрения криптографии состоит в том, что создается пара из открытого и закрытого ключа. Закрытый ключ разделяется на части, которые передаются членам избирательной комиссии – а они, как и на обычных выборах, представляют самые разные политические силы – например, в этот раз одним из членов комиссии был Григорий Мелконянц из “Голоса“. Главное здесь это то, что закрытый ключ не будет известен никому вплоть до момента его “сборки” – а открытый ключ, наоборот, будет опубликован во время голосования. Происходит процедура генерации и разделения ключей в торжественной обстановке, с банкетом, фуршетом, журналистками с декольте – в общем, “сожалею, что не был при сей баталии хотя бы мичманом!”

Дальше происходит собственно голосование – пройдя авторизацию на “Госуслугах” или mos.ru, избиратель получает от сервера регистрации уникальный номер (GUID) и перенаправляется на сервер голосования, по адресу “$host/election/check/$guid” (строка 94 файла Ballot.php в приложении form, опубликованном в ДИТовском гитхабе).

Сервер голосования – это приложение ballot (обратите внимание, что работало оно на другом домене – авторизация происходила на 2020og.ru, а собственно голосование – на elec.moscow, можно считать это демонстрацией возможности разделения авторизации и голосования), и там нам очень интересно содержимое файла election.js – точнее, то, что начинается после 243 строки. Там происходит следующее: с помощью библиотеки NaCl создается пара из “пользовательского” открытого и закрытого ключа, случайным образом выбирается значение nonce, сообщение из выбора избирателя и nonce зашифровывается сначала с помощью закрытого ключа избирателя, а затем – с помощью открытого ключа системы голосования. Пара из зашифрованного таким образом сообщения и открытого ключа избирателя обладает следующим очень полезным свойством – зная закрытый ключ системы голосования, можно убедиться, что сообщение (голос) зашифровано именно закрытым ключом избирателя, и никаким другим; не зная закрытого ключа избирателя, невозможно “подменить” голос; не зная закрытого ключа системы голосования – нельзя сделать с этим сообщением вообще ничего.

Затем пара из GUID и зашифрованного голоса отправляется на сервер голосования, где GUID проверяется на достоверность – что он действительно был выдан сервером регистрации, и по нему еще не голосовали, а зашифрованный голос в случае успешной проверки сохраняется – в данном голосовании в блокчейн, но в принципе это может быть любая база данных или вообще файлик на диске. Списки проголосовавших избирателей доступен наблюдателям, список зашифрованных голосов – вообще всем (в ходе голосования на специальном сайте транслировались транзакции блокчейна, а раз в полчаса они выгружались в файлы csv).

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

Попробуем теперь перечислить свойства такой системы.

  • Получить GUID и проголосовать могут лишь зарегистрированные избиратели – это обеспечивается не только криптографией, но и тем, что авторизацией пользователей занимаются “Госуслуги”;
  • Cервер голосования не может «вбрасывать» в хранилище голоса по своему усмотрению – их не может быть больше, чем на сервере авторизации было создано GUID’ов (список избирателей с отметками, кто голосовал, а кто нет, доступен для просмотра наблюдателям, как и на обычных «бумажных» выборах);
  • В ходе голосования голос пользователя расшифровать нельзя (и, допустим, отклонить его под видом технической ошибки);
  • После голосования голос пользователя нельзя изменить (так как никому, кроме самого пользователя, неизвестен закрытый ключ – и то для его сохранения надо предпринять некие усилия);
  • Каждый голосовавший может найти свой голос в опубликованных результатах;
  • Каждый может самостоятельно проверить правильность подсчета голосов;
  • Если сервер авторизации не сохраняет выданные пользователям GUID’ы, а сервер голосования не сохраняет связку между GUID и голосом (тут придется поверить разработчикам и эксплуатантам на слово – но скорее всего, это так) – никто не может узнать, какой голос принадлежит какому пользователю. Кстати, обращу внимание, что для раскрытия тайны голосования требуются согласованные действия операторов сервера авторизации и голосования – собственно, поэтому этот протокол и называется “протоколом двух агентств”.

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

Теперь перейду к плохому. Во-первых – зачем я полез смотреть код? Полез я туда именно для того, чтобы посмотреть, какой конкретно протокол голосования там реализован, и повторюсь, остался более-менее доволен увиденным – но хочу сказать, что программистом на PHP и Javascript я не являюсь, и гораздо проще было бы прочитать описание алгоритма голосования в более явном виде. Те же ГОСТы 34 серии предусматривают документ под названием “Описание алгоритма” – и может быть, я бы успокоился, увидев его и сравнив с реализацией. Кстати, еще две шпилечки в адрес ДИТа – во-первых, на вопрос “где же, все-таки, предусмотренная ГОСТами документация”, был дан ответ в духе “ну мы систему запустили, документацию напишем потом”. Хочу заметить, что у них на сайте выложен ГОСТ 34.201-89, а жить по нему они не хотят – там ясно сказано, что документ под названием “Описание алгоритма”, например, пишется на этапе технического проекта, еще до разработки каких-либо программ, и уж точно – до ввода в эксплуатацию. Точно так же хотелось бы напомнить о существовании ГОСТ РД 50-34.698-90, где можно увидеть мои хотелки в плане описания криптографических протоколов в разделе 7.1.

Вообще, в плане открытости и прозрачности электронного голосования есть куда расти. Это вовсе не какие-то абстрактные соображения, информация о работе системы и том, как в ней все устроено, должна быть доступна для широкого круга заинтересованных лиц, а не избранных “экспертов” – с которыми еще и делились информацией крайне неохотно. В противном случае мы получаем, например, пресловутую публикацию “Медузы” о том, что оказывается, если знать ключи шифрования и случайное число (то самое nonce), выбранное браузером пользователя при подготовке зашифрованного бюллетеня к отправке, можно проверить, правильно ли учтен этот бюллетень в итоговом протоколе. Открытие это сродни торжественной констатации факта “вода – мокрая”.

Вообще, во многих алгоритмах тайного голосования возможность проверить правильность учета своего бюллетеня, найдя его в итоговом протоколе, предусмотрена штатно (к ним относятся и вышеназванные) – хотя тот же Шнайер все же намекает, что такая возможность при неправильном ее использовании – прямой путь к организованной скупке голосов. Здесь же получилось так, что из-за некоторой скрытности авторов системы голосования возможность проверить правильность своего голоса журналисты объявили “уязвимостью”.

Довольно странно была организована и публикация исходных кодов системы – опубликованы были лишь два обеспечивающих голосование веб-приложения и код смарт-контрактов блокчейна, причем некоторые особенно интересные с точки зрения стойкости шифрования и сохраняемой информации места в исходном коде были почищены. Примерно так же выглядела и переданная рабочей группе “документация”, причем местами доходило до смешного – цитирую один из документов: “хеш длиной YYY кодируется в XXX для сохранения целостности”. При этом узнать длину хеша и способ его кодирования можно было совершенно тривиальным образом – например, открыв отладчик страницы во время голосования или заглянув в опубликованные исходники. Стоит еще сказать, что местами исходный код производит впечатление полуготового прототипа, к примеру, в некоторых местах остались комментарии в духе “удалить после тестирования”.

Кстати, к вопросу об отладчике – получить представление о работе системы голосования можно было бы во время тестирования. К сожалению, тестовое голосование было доступно лишь для избирателей, уже имеющих право голоса на реальном голосовании – то есть жители Московской области, желающие посмотреть, как что там устроено, оказались в пролете. К настоящему тестированию, с другой стороны, это не имело никакого отношения – возможность проголосовать давалась лишь один раз, так что сделать несколько попыток и посмотреть, “что будет, если” было невозможно.

Еще одно странное явление – это подключение некоей “системы антифрода” (по словам представителей ДИТ), которая изначально не была заявлена. Фактически на каждую веб-страницу голосования внедрялся посторонний код на Javascript, не выложенный в публичный доступ заранее.

Скажу еще немного о блокчейне. Довольно часто говорят, что именно благодаря блокчейну эта система голосования надежна и безопасна. Вот даже на ютубе в комментариях задали вопрос – “СМИ писали, что система надёжно защищена и использование блокчейна гарантирует от подмены голосов и деанонимизации, так ли это?” – на самом деле это не совсем так. Блокчейн обеспечивает хранение уже принятых голосов, и существенно затрудняет какие-либо изменения данных постфактум – но в “модели угроз” для электронного голосования это лишь один из многих рисков. О том, как система защищена от подмены голосов и деанонимизации я сказал выше, блокчейн как таковой для этого не нужен. Впрочем, если в этот раз блокчейн работал почти хорошо (за исключением его “падения” на несколько часов в первый день голосования) – то почему бы и нет? С другой стороны, представляется, что блокчейн в целом – это “узкое место” системы, Александр Щербаков высказывал свои соображения по этому поводу.

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

Это все может показаться придирками – но не устану ссылаться на опыт Эстонии, где описания системы электронного голосования для любой аудитории – от обывателей до специалистов – совершенно официально опубликованы на сайте тамошнего избиркома, а полный – вплоть до возможности собрать свою работающую систему голосования, полностью повторяющую настоящую – комплект исходных кодов выложен на все тот же гитхаб. Это очень полезно с “исследовательской” точки зрения, а один из основных принципов современной криптографии состоит именно в открытости криптографических систем для изучения.

В целом, конечно, вопросы к разработчикам имеющейся системы голосования – скорее не технические, а организационные. Повторюсь, что с точки зрения используемых протоколов голосования система довольно адекватна, а с точки зрения реализации – к сожалению, пока приходится верить на слово, что используемая система голосования совпадает с тем, что было показано публике. В будущем, конечно, хотелось бы иметь возможность изучить систему голосования не только по кускам кода на Github, а еще и по более-менее нормальной документации, причем целиком, а не отдельными частями “тут покажем, тут не покажем”.

Диалоги про демократию

monarch

Замечу, что 99% диалогов с борцами за чистоту выборов заканчиваются тем, что они скатываются в авторитаризм в диапазоне от просвещенной монархии до диктатуры Туркмен-баши.