Представитель Шуры Люберецкого в ЖЖ (brat_luber) wrote,
Представитель Шуры Люберецкого в ЖЖ
brat_luber

Categories:

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

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

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

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

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

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

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

Дальше происходит собственно голосование – пройдя авторизацию на “Госуслугах” или 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, а еще и по более-менее нормальной документации, причем целиком, а не отдельными частями “тут покажем, тут не покажем”.

Запись опубликована в блоге Шуры Люберецкого. Вы можете оставлять свои комментарии там, используя свое имя пользователя из ЖЖ (вход по OpenID).

Subscribe

Recent Posts from This Journal

  • И еще про Code of Conduct

    Будет и у eddy_em праздник — разработчики Rust посрались по поводу CoC и будет теперь у нас два раста — просто Rust и ПедеRust!…

  • Очередной наброс

    В 2021 году умеют работать в Unix-подобной командной строке не виндузятники (с ними все понятно), и не линуксоиды (это в массе своей позеры,…

  • Еще несколько слов про отечественное айти-образование

    Я все никак не соберусь и не напишу обещанные «многабукв» про околоайтишное образование — но вот еще маленький фактик в копилку.…

  • Post a new comment

    Error

    default userpic

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 7 comments