Как стать автором
Обновить

Медуза, паспорта и говнокод — почему номера паспортов всех участников интернет-голосования попали в Интернет

Время на прочтение 5 мин
Количество просмотров 58K
Всего голосов 146: ↑130 и ↓16 +114
Комментарии 401

Комментарии 401

у нас 10^10 вариантов

значение(я) которое нужно использовать для подмешивания к хэшу (оно будет общее для всех хешей)

А вот тут проблема, где хранить это общее значение? Как минимум сервер в нем нуждается и если соль утекла, останется вычислить хеши все тех же 10^10 вариантов.

С самим номером и хранить соль. В чём суть — на каждый номер нужно будет полный перебор запускать, на каждый 10^10 вариантов проверить

Если соль уникальная для каждого номера, тогда ок.

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


Уникальная соль работает, когда она уникальная для какого-то одного идентификатора (логин), а перебирать надо другой (пароль).

Подведу итоги:
1. Уникальную соль на базе номера нельзя сделать, потому что это принципиально ничего не меняет
2. Уникальную соль не на базе номера, например гуид или время, тоже нельзя, потому что как потом идентифицировать?
3. Не уникальная соль может утечь с базой.
Какие варианты остались?

Неуникальная соль для борьбы с радужными таблицами + сложный долгий хеш.

Ну да, какой-нибудь bcrypt/scrypt или PBKDF2.
В качестве уникальной соли можно использовать, например, ФИО или дату выдачи паспорта.
А найти её там как, если нехешированный номер паспорта не хранится?
Да-да, пока вы отвечали, я уже понял, в чем тут проблема.
Спросить у пользователя? Он ведь знает свое ФИО и дату рождения…
Да, да. Просто взять из паспорта любое поле в качестве соли. Дату рождения, выдачи, имя, фамилию, все вместе. Член УИК при проверке должен видеть паспорт перед собой по процедуре.
Член УИК при проверке должен видеть паспорт перед собой по процедуре.

или не паспорт....


http://cikrf.ru/izbiratel/interesting/labzin/otv.html


  • военный билет, временное удостоверение, выдаваемое взамен военного билета, или удостоверение личности (для лиц, которые проходят военную службу);
  • временное удостоверение личности гражданина Российской Федерации, выдаваемое на период оформления паспорта в порядке, утверждаемом уполномоченным федеральным органом исполнительной власти;
  • документ, удостоверяющий личность гражданина Российской Федерации, по которому гражданин Российской Федерации осуществляет въезд в Российскую Федерацию в соответствии с федеральным законом, регулирующим порядок выезда из Российской Федерации и въезда в Российскую Федерацию (для лиц, постоянно проживающих за пределами территории Российской Федерации);
  • справка установленной формы, выдаваемая гражданам Российской Федерации, находящимся в местах содержания под стражей подозреваемых и обвиняемых, в порядке, утверждаемом уполномоченным федеральным органом исполнительной власти.

Справедливо, но авторы (менеджеры проекта) вот этого всего (судя по результату) то же не предусматривали.
взять из паспорта любое поле в качестве соли. Дату рождения, выдачи, имя, фамилию, все вместе.
Во-первых, термин «соль»/«синхропосылка»/«IV»/… это данные, которые хранятся совместно с результатом криптографической операции, т.е. этот термин в данном контексте неприменим. Заметим так же, что хотя идея расширить область перебора сама по себе разумная, но в такой трактовке область перебора увеличивается незначительно, поэтому она ничего дополнительного не гарантирует. Скажем, если у нарушителя уже есть паспортная база РФ или её существенная часть (сотовые операторы, банки, и т.п.), всего ж, с точностью до порядка, 150 млн. записей.

Во-вторых, действительный номер паспорта, в обезличенном виде, «персональными данными» не является (по крайней мере, МВД предоставляет сервис по проверке номера). Но, совместно с именем и фамилией, это уже точно не обезличенные, и это уж гарантировано «персональные данные», поэтому приложение обязано удовлетворять требованиям соответствующего закона.

Наверное, оставаясь в сравнительно “обезличенном” виде, можно было бы добавить собственно номера паспорта: дата выдачи, код подразделения, номер ранее выданного паспорта, но смысл такого добавления всё равно неясен.
Во-вторых, действительный номер паспорта, в обезличенном виде, «персональными данными» не является

Тогда зачем Минкомсвязи устроило истерику «у нас там не номера, а непонятные значки» и «мы ничего не публиковали, кто устроил утечку, тот и виноват»?

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

У Минкомсвязи (в истерике) и МВД могут быть разные мнения на сей счёт. А уж Медуза? Ну Медуза, уж придумает о чём написать, причём на любую тему, это ж её хлеб с маслом.
Вы абсолютно правы, написал не очень подумав. Более, как мне кажется, хорошая схема решения.
Да, там, термин «соль» применён корректно.

В той схеме неплохо, что и рабочий код, и код подбора, могут работать в одинаковых условиях, т.е. многопоточно, векторно, и т.п. (с точностью до коэффициента, рабочий код проверяет ~1/2 базы, код опробования всю базу, но, вероятно, код опробования более оптимизирован)

Но назвать «ту схему» «решением» — нельзя.

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

Как бы, если взглянуть на возможности потенциальных нарушителей к опробованию номеров по сравнению с возможностью компьютеров избирокома или наблюдателей:
  • Вычислительные возможности одного суперкомпьютера, скажем, Сбербанка в 105 раз выше;
  • «Кул-хакеры» собирают ботнеты из 106 узлов таких же компьютеров;
  • Более крутых, наверное, можно и не обсуждать.


При этом, если взглянуть на график распределение серий паспортов, можно заметить, что для раскрытия 80..90% номеров паспортов требуется осуществить не более 107 опробований. Т.е. если член избиркома или наблюдатель проверяет номер паспорта за ≃1 секунду, то более менее крутой нарушитель раскроет 80% номеров за ≃200 секунд.

Таким образом, задачу защиты собственно номера паспорта «та схема» не решает.

Мало того, «та схема» не решает и задачу защиты от критики со стороны пристрастных аудиторов. В самом деле, с точки зрения аудитора безопасности даже уже один раскрытый номер паспорта это уже вполне себе результат. Но, учётом того, что доля удалённо голосующих ≈ 5...10%, то каждые 10...20 опробований будут выдавать очередной номер паспорта (т.е. каждые 20...40 с даже для точно такой же машинки, как в УИКах).

Лично я бы, за «решение» гипотетической задачи «защитить номера паспортов от раскрытия» мог бы начать думать бы, если бы потенциальный нарушитель мог бы восстановить номер паспорта с вероятностью не выше 10-2 в течении нескольких лет, как минимум миниморум. Ну, а поскольку, все мы люди, все ошибаемся, то для надёжного «решения» наши оценки сроков и вероятностей должны быть на много порядков лучше. Однако, ни в самой этой статье, ни в комментариях, увы, как мне кажется, нет ничего и близко к «решению» сей гипотетической «задачи».

Суть в том что мы хэшируем не просто номер паспорта, а номер паспорта + что-то еще, чем усложняем перебор.

Неуникальная соль — это вообще не соль, а перец.


Соль хранится вместе с хэшем. Откройте /etc/shadow на любом линуксе и посмотрите: там знаком $ разделены идентификатор типа хэш-функции, соль и сам хэш.


Смысл соли не в том, что она секретная — ровно наоборот. Смысл в том, чтобы удлиннить плейнтекст случайными данными настолько, чтобы rainbow tables ничего не дали.


Возможных номеров паспортов, конечно, совсем немного по сравнению с возможными паролями, потому соль поможет не сильно — на современном оборудовании перебрать тот же sha-256 даже с каждой конкретной солью 10^10 комбинаций не так долго (а учитывая, что известны невалидные номера серий, и того меньше) — ну, вместо того, чтобы расшифровать всю базу на подручном ноутбуке, арендовали бы кластер в амазоне на денек, вот и все.


Потому в дополнение к соли еще надо ооочень медленную и memory hard хэш-функцию. Argon2i, например. Этого бы вполне хватило, чтобы расшифровать было достаточно дорого и бессмысленно — в данном конкретном случае (нафиг нужны голые номера паспортов через три месяца, и зачем тратить десятки тысяч долларов на их расшифровку)?


А по-хорошему, конечно, если исходить из необходимости работать офлайн, надо еще дополнительно каждому УИКу зашифровать данные его публичным ключом. Но такая инфраструктура за пару дней не развертывается, конечно.

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

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

С этого момента поподробнее. Как это у вас будет работать, извините?

Либо вы в миллион раз замедлите также и проверку каждого номера в приложении, либо ничего не замедлится и у переборщика…
Применительно к degvoter — никак не будет работать без требования впридачу к номеру паспорта ещё каких-нибудь данных для поиска соли в базе.
Вы про это?
Я про то, что если в техзадании написано что вводится только лишь номер паспорта, то «ещё каких-нибудь данных» у вас нету. То есть придётся тупо перебирать уже в самой программе все варианты.
Претензии к тому, кто составлял такое ТЗ.

А в чем проблема с тем, что проверка номера паспорта в приложении займет пару секунд?

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

Это если сделать много раундов. Если же делать один — то код усложнится, а устойчивость к взлому — не возрастёт. Зачем такое нужно?

Для нормальной проверки из приложения какая разница, какая там соль?


Как раз один хэш должен вычисляться 2-4 секунды на среднестатистическом современном CPU. Для проверки конкретного паспорта это вполне приемлемая задержка. А отбрутфорсить хэш уже будет настолько дорого, что это теряет всякий смысл.

Для нормальной проверки из приложения какая разница, какая там соль?
Нормальная проверка в приложении сводится к тому, что человек вводит номер паспорта (и только и исключительно его) — и получает ответ: голосовал человек или нет.

Для проверки конкретного паспорта это вполне приемлемая задержка.
Алё, алё, алё! Для тех кто, в танке: типичный случай для данной программы — это не ситуация, когда паспорт в базе есть, а как раз наоборот — вариант, когда его там нет!

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

А вы тут накрутили раундов столько, что у вас одна проверка две секунды занимает. Миллион раз по две секунды — это нифига не «приемлемое время для выдачи бюллютеня».

А, ну да, туплю :-)


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

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

Радикальное решение — блум-фильтр, который можно настроить так, чтобы повторно проголосовать могли, скажем, 0.01% (или даже 1%: тут же важно, что блум-фильтр не даст вам простого способа определить кто именно может повторго головать, если у вас нет базы со всеми проголосовавшими, так что реальное влияние на результаты будет пренебрежимо мало).

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

Блум-фильтр — красивая идея, но всегда может возникнуть подозрение, что он настроен уж слишком специально. :-)

Это вообще большая проблема ещё с античных времён.

Но лучше всего её описывает Мерфи: Любая, даже самая сложная, проблема обязательно имеет простое, легкое для понимания, неправильное решение.

И дальше у вас дилемма: сделать то, что реально решает проблему — и получить полный ушат… ммм… «критики в прессе». Либо применить вот то самое… а потом ваши потомки будут вас проклинать «за развал страны».
Алё, алё, алё! Для тех кто, в танке: типичный случай для данной программы — это не ситуация, когда паспорт в базе есть, а как раз наоборот — вариант, когда его там нет!

Это не так: отметка о том, что человек зарегистрирован на электронное голосование (или откреплён на другой участок), у УИКа уже есть в бумажных списках. Незарегистрированных нет никакого смысла проверять программой.
Миллион раз по две секунды — это нифига не «приемлемое время для выдачи бюллютеня».

приемлемое. Думаете сотрудник УИК быстрее вписывает данные в реестр избирателей? Или давайте поговорим об эффективности "голосования на дому"?
К тому же каждый участок формируется так, чтобы на нем было вполне внятное количество избирателей. Я не помню точных значений. Но вряд ли участок — это больше 10-20 тыс. избирателей, а скорее даже попросту несколько тысяч. На 5-6 членов УИК. Можете посчитать пропускную способность )

По закону — не больше трёх тысяч избирателей на одном участке.
А как вы в таком случае по базе будете искать?
Это если вам нужно хешировать пароли, то, действительно, правильное решение это хеширование конкатенации соль+пароль. Но в данном случае нам нужно искать по полученному набору, поэтому разная соль для каждого паспорта не подходит. В данном случае нужно нестандартное применение алгоритма хеширования (не имеющее в данный момент таблиц подбора) + математическое замедление вычисления хеша.

Я не безопасник, но уникальную соль можно получить из того что имеем.
В паспорте помимо номера есть и другие данные.


Солью может быть sha256(Последняя буква имени + Последняя буква фамилии)


Тогда итоговый хеш будет таким:
sha256(Номер паспорта + sha256(Последняя буква имени + Последняя буква фамилии))


Но я думаю самым разумным решением было бы не хранить эти данные дольше чем нужно (как и любые другие данные)


UPD: Уникальную в том смысле, что не общую соль для всех.

Не, смотрите. Там член УИК вводит именно номер паспорта и больше ничего. Никаких других данных.
Сгенерировать соль из номера, будет достаточно.
Так это и есть нестандартное применение хеша. Но этого недостаточно. Нужно чтобы хеширование шло в миллион раз медленней, чем просто вычисление одного sha256 хеша
Уязвимость не в том что sha256 слишком быстрый, уязвимость в том, что количество возможных вариантов конечно и не такое большое — 10^10. Нужно увеличить количество этих вариантов.
Я бы взял хеш от номера, разбил бы его на 2 части, первую часть склеил с началом номера, вторую с концом и вычислил бы хеш от того, что получилось.

Разве вы не изобрели просто новую хеш функцию?

Посмотрите внимательно у вас всё равно количество входных данных осталось то же — 10^10. Просто усложнилась хеш-функция, которая стала составной. В этом как раз суть проблемы — соль неприменима в этом режиме использования.
Да, вы правы. Проблема достаточно интересная, глубже, чем кажется на первый взгляд.
Это как раз к вопросу почему при таких задачах нужны люди с опытом по криптографии/ИБ
Правильно решить эту задачу может человек, который знаком не только с тем как работает хэш-функция, но и с методами атак на них.
Вы же постепенно шаг за шагом задумываетесь о тех вещах, которые разработчик с соответствующим опытом уже знает :-)
Проблема стара как мир и имеет решение тривиальное до безумия. Тупо берёте произвольную соль и считаете SHA512(соль+номер) — миллион раз. Подбираете число повторений, чтобы вся ваша таблица обработалась за пару часов. Всё.

Соль нужна большая и случайная — она защищает вас от того, что кто-то вложится в суперкомьютер и научится все таблицы во всех программах, так устроенных, проверять одновременно. Тратить миллион часов машинного времени на одну единственную табличку — никто не будет.
Простое же решение — солью должна быть фамилия избирателя (производное от нее).
В программу вводится только номер паспорта.

И да — возможно это не самое лучшее решение, да, но у исполнителей точно не было возможности на него влиять.
как раз в замедлении весь цимес. Если у вас скорость алгоритма 1 хэш в секунду, то вам на 1 паспорт понадобится 10^10 секунд, то бишь более 300 лет. Сверху все это солится как защита от радужных таблиц.
В замедлении свои минусы, нужно подобрать такое замедление, которое не задушит свой сервис, но при этом перебирать было бы достаточно долго.
Допустим одна секунда на хэш это многовато, допустим есть 100 миллионов избирателей с правом голоса, чтобы высчитать хеши для всех их нужно потратить более 1000 дней процессорного времени. Тогда чтобы уложиться в один день выборов, нужно не менее 1000 серверов только на вычисление хешей. Такие вот расчеты на коленке.
нужна 1000 потоков, а не серверов. Задержка не обязательно же лочит весь сервер. Поток вполне может отдавать управление на время ожидания
Мне не известны хеш алгоритмы, которые в процессе вычисления чего то ожидают и процессор простаивает.
а кто мешает после отработки алгоритма подождать перед возвратом результата
result = sha512(input)
sleep 1
return result

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

В этом случае да, только раунды
Можно выполнять на клиенте эту функцию, отправлять на сервер дайджест, сервер выдает ответ аутентификации с задержкой, но не криптографическим методом, а тупо wait.
Таким образом ресурсы свободны, система проверки работает. Аргон на клиенте, сервер о данных может вообще не знать.

Это тоже можно менять, например регламентом заставить вводить дату рождения

Я не безопасник тоже) Но такой вопрос, а чем не походят адреса ячеек памяти в которых хранятся данные? Уникальные для каждого. Или например какие-либо данные из кеша приложения, или другой области памяти? Тот же рандом символов.
Во-первых, ячейки памяти не уникальны, если только ОСь была скомпилена с рандомизацией памяти (что редко вообще делается). Данные из другой области памяти — тоже не рандом, можно использовать псевдорандом генератор, другой вариант микрофонные данные для тру рандома с компенсацией дискретизации. В любом случае соль нужна, можно даже использовать дату создания записи для соли. Вопрос в том, насколько это усложнит подбор. Если известна функция и общий набор данных подбор не такая сложная штука.

Если у нас нет идентификатора гражданина по которому можно сделать условный WHERE, то никакие другие поля той же строки таблицы, где записан хэш номера паспорта мы использовать не можем для проверки. Условие WHERE t.passport_hash = hash(CONCAT(t.created_at), :input)) будет работать недопустимо медленно на миллионах записей, а защиты толком не даст, если база утекёт. Только внешняя фиксированная соль, если из входных данных у нас только номер паспорта.

С номером паспорта никакая соль не спасет. Аргон или хотя бы бкрипт для замедления подбора. Соль нужна только для защиты от радужек. В данном да и в любом случае WHERE t.passport_hash = hash(CONCAT(t.created_at), :input)) принципиально равно WHERE t.passport_hash = hash(CONCAT(t.salt), :input)) потому что оба не предсказуемы и в таблицах не используются. На кой смысл тратить циклы на псевдорандом если можно получить аналог из данных, которые по-любому сохранять.

Аргон уже лучше. Но я бы для полной безопасности аргон на клиента закинул, тогда можно разделить сервер хранения данных и сервер авторизации (проверки входных данных — верен ли паспорт или нет).
В итоге пользователь ввел данные в клиент. Клиент отправил в сервер авторизации закриптованные данные ключом, что он может открыть (делается через общий публичный ключ). Сервер авторизации подтверждает данные аргоном на сервер записи данных. Сервер записи данных получает другой аргон от клиента и закриптованные данные. В итоге увод базу крипты ничего не получает, т.к. надо увести еще и базу авторизации.
Защитить сервер авторизации намного проще чем сервер с открытой базой данных вплоть до правил в железном фаерволе и отключить все остальное фаерволлом.
Защитить сервер можно, но что делать, если связь по каким-то причинам отсутствует? Как в таком случае проверить статус голосования?
Блокчейн? Прямое его предназначение. Первый голос будет считаться верным. Или я что-то не правильно понял?
Приехали вы на дом для голосования. У вас на руках мобильный терминал с клиентской частью. А интернета, как назло, нету во всём городе. Какая-то зараза оборвала магистральный кабель, починят завтра утром. А перед вами гражданин, желающий проголосовать, и вам надо проверить, не проголосовал ли он уже электронно.
Для того и есть блокчейн.

Мы его голос записываем с меткой секунд от текущего записанного блока (если его запись еще не в блокчейне). Как только синхронизируем блокчейн будет ясно.

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

И не нужно доверять. Если есть запись точь-в-точь секунда в секунду от блока такого-то — инвалидировать обе транзакции к чертям собачъим и маркировать как «еще не голосовал». Самая ранняя выигрывает.
Вот только голосование у нас тайное, и не записывается кто как проголосовал. Записывается только сам факт электронного голосования, чтобы не дать человеку проголосовать второй раз. При бумажном голосовании вообще известен только суммарный итог по участку. Как вы собираетесь не дать проголосовать дважды, если нет связи с базой уже проголосовавших электронно?
Это никак не мешает не учитывать сторону его голоса. Нам важен только факт его голосования.
Хорошо. У вас есть результат по электронному участку, 100 за, 100 против. Есть результат по бумажному участку, 50 за, 50 против. Вы знаете, что три человека проголосовали дважды, как надо скорректировать результаты?
Как сейчас это учитывается? Как сейчас уникальность голосования блюстят? Тебя проверяют на месте (авторизация), потом ты голосуешь без свидетеля (отправка транзакции) и уходишь. Верно?

Ну так что мешает это реализовать электронно?
Авторизация? Паспортные данные аргоном закрыты с солью. За кого проголосовал можно отдельно регистрировать, можно туда же или в отдельную бд. Условные саб-блоки можно вообще подписывать геоданными или ключом с улицей в зашифрованном виде. Методик туча, я не буду тут расписывать халявный алгоритм. Факт в том что подсчитать с криптографией можно лучше нежели сейчас и совсем необязательно привязывать голос к данным паспорта если можно подписывать тучу транзакций едино без указателя кто за кого проголосовал (грубо говоря как пункт голосования) (принцип работы шаффлера, монеро и зк-снаркс).
Полный перебор не нужен т.к:
— номера паспортов не уникальны (не спрашивайте меня, я не отвечу), просто посмотрите на портал госуслуг и вспомните что там СНИЛС, а не номер паспорта. Подробностей тут не расскажу
— в отличие от других кодов у него нет проверочного номера
— первые 2 цифры серии паспорта — это код субъекта федерации(коды по ОКАТО), следующие 2 цифры серии — это номер года печати бланка, как правило соответствует или предшествует дате выдачи паспорта.
— остальные цифры инкрементальны, но нет какого-то известного алгоритма как они распределялись по УФМС/ОВД для выдачи поэтому нельзя оценить по номерам паспортов, например, общее число выданных паспортов за год или дату выдачи конкретного.
Об этом очень подробно написал Иван Бегтин у себя в ТГ канале.
Сочетание «серия + номер» паспорта — уникально и однозначно определяет бланк паспорта. Но паспорт подлежит замене по возрасту, при утере, при смене имени и/или фамилии. При этом новый паспорт выдаётся на новом бланке, с другими серией и номером.
СНИЛС же выдаётся один раз и не меняется, поэтому может служить уникальным идентификатором.

У человека может быть два СНИЛС. Так как Пенсионный фонд большой и неповоротливый, то разные его отделения используют разные СНИЛС. Это из практики и общения с ПФР.

Странно. У меня практика ровно противоположная. Мне оформляли первый раз СНИЛС в школе, где я подрабатывал. Потом я закончил универ и устроился на фуллтайм. Бухгалтер, не зная о школе, оформила СНИЛС ещё раз.

В результате я получил две карточки, где были разные регионы (Москва и Московская область) — но одинаковый номер.

И это было много лет назад, больше 10… у них там регресс случился, что ли?
Насчёт порядка нумерации паспортов надо наших солсберецких Петрова и Баширова спрашивать.
… следующие 2 цифры серии — это номер года печати бланка, как правило соответствует или предшествует дате выдачи паспорта.

Похоже у меня бланк из будущего.
Оно зашито в исполняемом коде сервера.
Как правильно написано, серия и номер паспорта составляют всего 10 цифр. Сами по себе эти цифры не являются персональными данными, так что утечка этой базы никому ничем не грозит, да и защищать тут нечего.
Именно. Она ничем не грозит. Но существование подобных программ с точки зрения программирования — это стыд и позор.
Второе — это чисто PR-проблема, если бы люди разобрались как работают хэши, сейчас бы мы Медуза не заявляла про то что паспортные данные попали в сеть. А ведь достаточно было всего лишь сделать сделать например миллион вложенных итераций хэша SHA256.

Ну вроде простейший прямолинейный кусок кода, 10 лет не писал на C# и всё понятно). Вы сами говорите, что это ничем не грозит. Ну те, кто это делал думали также. В чём их проблема и почему стыд и позор тогда?

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

Сейчас же все огребают от заголовка «Медузы» про утечку «паспортных данных» — и сильно страдает паблисити, т.к. большинство людей словосочетание «паспортные данные» понимает как набор паспортных данных, а не один только номер.
Сейчас же все огребают от заголовка «Медузы»

Но это уже совсем другая проблема («учёный изнасиловал журналиста»)
No man is an island entire of itself; every man
is a piece of the continent, a part of the main;
if a clod be washed away by the sea, Europe
is the less, as well as if a promontory were, as
well as any manner of thy friends or of thine
own were; any man's death diminishes me,
because I am involved in mankind.
And therefore never send to know for whom
the bell tolls; it tolls for thee.


Не бывает изолированной проблемы в вакууме, это всегда цепочка проблем, гасить которую чем раньше — тем проще и лучше.
Личные данные как никак утеряны. Как минимум пользователям не хочется чтобы их данные вот так вот просто могли утекать от гос органов.
Да и в + к клиент-серверной — обновлять проще, поддерживать тоже, а также на ходу менять алгоритмы шифрования и обеспечивать безопасность не только данных, но и приложения. + найдутся люди которые захотят и серв ломануть, возможность подловить или найти себе специалистов (но это так скорее вымысел).
А ведь достаточно было всего лишь сделать сделать например миллион вложенных итераций хэша SHA256.

А можно тут по подробнее? Просто для не посвещенных не очень понятна фраза «миллион вложеных итераций»
Т.е. для вычисления hash делаем не
hash = sha(номер+соль), а
i = 1 000 000;
hash = номер + соль
while(i --> 0) hash = sha(hash);
?
И уже учтенные значения вычисляем так же и сравниваем hash?
И уже учтенные значения вычисляем так же и сравниваем hash?
В смысле — проверяем на каждом шага из миллиона? Нет. Просто тупо вычисляем sha(sha(sha(...))) миллион раз.

Соль нужна, чтобы нельзя было просто раз и навсегда вложиться, построить радужные таблицы (за миллион долларов) и использовать их для всех, кто такой метод применяет.

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

так что утечка этой базы никому ничем не грозит, да и защищать тут нечего.
Проходите, товарищи, не задерживайтесь.
Не уверен, является ли номер паспорта ПДн, согласно последней букве закона (может и является), но чисто с человеческой точки зрения это явный и серьезный косяк, и защиать тут, безусловно, есть чего.

PS: если защищать там нечего, почему тогда база не plaintext?

Почему это не являются? По ним можно однозначно идентифицировать человека? Можно. Всё, это ПД.

То есть если я сейчас здесь напишу десять неких цифр, например, 2003 812958, то все — я на ваших глазах персональные данные разгласил? Ну-ну.

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

Выше человек утверждает, что сам по себе номер паспорта — это ПД потому, что "по нему можно однозначно идентифицировать человека". Насчёт же того, входит ли в тайну голосования сам факт голосования — это вопрос открытый. Те же члены избирательной комиссии точно имеют доступ к спискам голосовавших, но не к тому, кто из них как проголосовал, при этом считается, что тайна голосования этим не нарушается.

Хорошо. Берем случайные цифры, идентифицируем по ним человека и что? Мы получили доступ к ПД? Безо всякого доступа к данным электронного голосования, реверса хешей и всей это ненужной работы?

Что нам дает доступ и реверс? Некий набор серий и номеров? Да. Но по ним нельзя идентифицировать человека, не имея доступа к другим ресурсам. А если у нас этот доступ есть, то мы может любого человека идентифицировать и без данных электронного голосования.

Тогда возникает вопрос — а где на самом деле идет реальная утечка ПД?

Насколько я понимаю, проблема в электронном голосовании, да еще с растяжкой по времени совсем иная. Проблема в том, как показала практика, что тут открывается большой простор для махинаций — люди (и это не единичный случай) голосовали по 2-3 раза в разных местах. И это мы еще не знаем сколько там было фейковых голосов, которые были просто вброшены в электронную систему.
Факт голосования тайной не является.

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

Вот и я о чем. Никто не мешает работодателю и без этой так называемой "утечки" теоретически просто поставить возле избирательных участков по человеку и "проверить, голосовал ли его сотрудник".

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

или не опустил в урну, или опустил в урну (если это не КОИБ) пустой лист, а бюллетень вынес с собой? Или сделал бюллетень недействительным — например, путем заполнения его "не по инструкции"

Что вам мешает проделать это всё на электронном голосовании?

Я сам электронно не голосовал, но предполагаю, что там попросту нет возможности поставить чекбокс в обоих окошках выбора и таким образом сделав электронный бюллетень недействительным. Максимум — можете не нажимать на кнопку "отправить голос", оставив электронное голосование в "открытом" состоянии. Но при сборе системы такие не проголосовавшие легко могут стать "согласен" — кто и как это проверит задним числом? Вы же знаете как у нас юзер сториз пишутся.

Была новость, что кто-то через веб-консоль заслал навалидный бюллетень, то есть испортил его.

Я видел в результатах РОВНО 1 НЕВАЛИДНЫЙ электронный бюллетень. Вообще с трудом представляю как это возможно ) Но это только говорит об уровне разработки, в которой на беке нет валидации аргументов )

Смотрите: перед отправкой бюллетеня на сервер он шифруется открытым ключом системы голосования, при этом закрытый ключ в этот момент вообще никому не известен, он был сгенерирован до начала голосования, разделен на части и роздан 5 «хранителям ключа» — так что «провалидировать аргументы на беке» при всем желании в ходе голосования будет невозможно, от пользователя приходит зашифрованное сообщение, которое бекенд должен просто сохранить, никак не проверяя (ну разве что длину его можно проверить в этот момент).

Дельное замечание, но не кажется ли Вам, что вся эта магия с шифрами должна происходить на бекенде? Потому что я не вижу от него прямой выгоды. Зато система сложнее Ну, и если шифрование джаваскриптом на стороне браузера, то все равно возможна утечка голоса по сайд каналам (вредоносные джаваскрипты в браузере на том же домене или внедренные со стороны пользователя). И можно было хотя бы валидировать контрольную сумму шифра или типа того

Нет, ни в коем случае. Любой нормальный протокол тайного голосования требует шифрования на стороне клиента. Утечка по сайд-каналам (через внедренный со стороны пользователя js, например) — это гораздо меньший риск, чем вот такое явное «нетайное» голосование с шифрованием только на бекенде.

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

> Почему я должен верить в то, что там действительно правильно реализованное шифрование, а не условный XOR?

github.com/moscow-technologies/blockchain-voting/tree/voting2020/elec2020 — изучайте.

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

Закрытый ключ разделен на части и роздан 5 «хранителям ключа». Или вы считаете, что Мелконянц из «Голоса» тут же сдал свою часть ключа кому надо?
github.com/moscow-technologies/blockchain-voting/tree/voting2020/elec2020 — изучайте.

гарантии того, что в проде тоже самое, что и на гитхабе? Это типичная "цепочка поставки" на самом деле, где атаковать могут каждый элемент


Или вы считаете, что Мелконянц из «Голоса» тут же сдал свою часть ключа кому надо?

почему я вообще должен ему доверять ?

> гарантии того, что в проде тоже самое, что и на гитхабе?

Как минимум клиентскую часть проверить на соответствие опубликованной вы можете.

> почему я вообще должен ему доверять?

Почему вы вообще должны кому-либо доверять? Я бы вообще спросил так: почему вы с такими параноидальными вопросами пишете комментарии на Хабре, а не живете натуральным хозяйством на заимке в тайге?

отвечу так — "если вы параноик, то это не значит, что за вами не следят" (с) /ну, про не-параноика тоже верно)

Толку от этой ссылки? У нас нет возможности проверить соответствует ли ее содержимое тому коду который реально работал на фронте и бэке, да и закладки в чужом и недокументированном коде искать тяжелая и неблагодарная работа. Я уже писал Вам что реальной проверкой стало бы создание альтернативного фронта, но серьезных возможностей для подобного действия создано не было.
> создание альтернативного фронта

Вы только что создали строчку в таблице оценки рисков — потому что тут же будут созданы не один, и не два, а несколько сотен «альтернативных фронтов», которые будут:

— голосовать всегда «за»;
— голосовать всегда «против»;
— записывать 100500 параметров пользователя, вплоть до размера ноги и клички собаки;
— просить от пользователя номер банковской карты и три цифры на обороте;
— делать много чего странного.

Готовы это обсудить?
Не вижу с этим проблемы. Пользователь в любом случае вынужден доверять какому-то источнику проверившему за него фронт. В моем варианте у пользователя будет выбор кому доверять. В существующем выбора нет — пользователь должен слепо верить организаторам.
К чему Вы это? С проблемой описанной по ссылке можно бороться только разрешением множественного голосования, это совершенно независимая тема.
Я к тому, что вы комментарием выше предложили максимально облегчить создание такого «скомпрометированного клиента».
Скомпроментированный клиент в любом случае будет создан. Это следует принять как аксиому и строить систему исходя из этого — она должна иметь возможность с такой ситуацией справиться. Security through obscurity никогда не работает. Выкладывание исходников вообще худший вариант в этом смысле — создать скомпроментированный вариант из рабочего гораздо проще чем рабочий из скомпроментированного.
> Security through obscurity никогда не работает.

У вас есть возможность объяснить эту азбучную истину представителям ЦИК?
Когда про электронное голосование рассуждают технари, то они нарушением тайны голосования считают перехват трафика по дороге к бэкенду. Но на практике гораздо более вероятное нарушение тайны электронного голосования — это начальник за плечом.

Против лома, как известно, нет приема.
Как предлагаете с этим бороться? Техническими средствами — боюсь, что никак, а раз так, то и в техническом дискурсе это обсуждать контрпродуктивно

Техническими средствами с этим можно бороться давая возможность пользователю голосовать более одного раза. Либо выдавая ему два пароля (истинный и ложный) которые он сможет использовать и которые будут для стороннего наблюдателя неотличимы, но в зачет пойдет только голос с истинным паролем. Либо просто засчитывая только последний поданный голос. Второе по всей видимости проще и понятнее, но первое интереснее тем что там можно разрешить пользователю проверять зачли ли его голос.
Просто технические обсуждения того, на клиенте или на сервере лучше шифровать голоса для обеспечения тайны голосования, напоминают выбор замка для сарая, у которого нет задней стены.
Ну в существующей схеме — да. Но для более совершенных реализаций это вполне актуальный вопрос.
Я думаю что на практике как раз проще организовать перехват трафика по дороге к бэкэнду. В этом сценарии начальнику достаточно посадить пользователя голосовать на заранее скомпроментированном устройстве. В текущей схеме голосования, к примеру, по моим прикидкам достаточно установить на компьютер специальный корневой сертификат для организации MITM атаки и разместить аппарат для проведения этой атаки в локальной сети. Сертификаты поставят сильно заранее «для поддержки отечественного шифрования», «меры обеспечения безопасности» и тому подобных вещей — сами по себе они не криминальны. А дальше директор предприятия получит от неизвестных небольшую коробочку которую нужно просто воткнуть в сеть и предложит сотрудникам проголосовать на территории предприятия. Это проще чем стоять у них за спиной и практически не обнаружимо на уровне голосующих сотрудников и наблюдателей.
этом сценарии начальнику достаточно посадить пользователя голосовать на заранее скомпроментированном устройстве.

В этом случае, может даже вестись запись видео прямо с видеовыхода компьютера.
Я согласен с tyomitch — странно обсуждать безопасность Бека, когда на входе такое

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

ага, но только при условии получении пароля по отдельному, защищенному каналу. Толку от пароля, если он так же пришел на скомпрометированный ПеКа.

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

Проще написать директору приказ по ведомству «Обеспечить возможность голосования сотрудников», на словах добавив «Ну вы же понимаете...» Дальше пусть сам выкручивается.
Стопку коробочек заготовят другие, директор просто получит одну по почте или в руки. Корневой сертификат поставит местный админ один (1) раз задолго до дня голосования в рамках какого-нибудь приказа по улучшению безопасности.
А у вас правда во время голосования за плечом стоял начальник?
Кстати, а как «нормальный протокол тайного голосования» может обеспечить то, что регистрируемые голоса вносятся живыми людьми, а не ботофермой с тысячей аккаунтов и не скриптом на соседней машине в сети ЦИКа, которому даже аккаунты не нужно создавать, достаточно доступа на запись в базу/блокчейн?
> ботофермой с тысячей аккаунтов

У вашей ботофермы есть тысячи подтвержденных аккаунтов в госуслугах, со всеми положенными вещами вроде СНИЛС и ИНН?

> скриптом на соседней машине в сети ЦИКа, которому даже аккаунты не нужно создавать, достаточно доступа на запись в базу/блокчейн

При разделении регистрации и голосования между двумя ведомствами (условно Ростелеком и избирком соответственно) избирком может, и рад бы вбросить — но не имеет доступа к регистрации, а Ростелекому (или другому оператору системы регистрации) голосование либо параллельно (какие-нибудь выборы муниципальных депутатов по району Новое Бенево), либо должно контролироваться наблюдателями по спискам избирателей.
Это точно так же как ЦИК формально независим от властей, а УИКи имеют большую независимость от ЦИКа. На самом деле мы видим явно централизованные фальсификации. Внедрение ещё одного игрока при нашей порочной системе поможет слабо, хотя чем больше здесь децентрализации — тем лучше.
> явно централизованные

Не совсем, тут довольно много заинтересованных сторон (и что для вас покажется совсем удивительным — некоторым нужны именно неискаженные результаты).
Это не отменяет того, что указ на фальсификации явно централизованный. На местах — да, выкручиваются как могут. Есть кластеры регионов с очень похожим почерком фальсификаций, а есть те, где фальсификаций меньше. Есть те, где подсчитано более-менее честно (с 2012 по 2019 год таким честно считающим регионом была Москва). Но если бы это были перегибы на местах — графики у Шпилькина были бы совершенно другие.

Т.е. у нас целые институты и ветви власти превращены в декорации (Дума, суды, ЦИК и т.д.), но это не означает полной однородности.
Я просто еще раз притащу сюда эту ссылку: www.rbc.ru/politics/18/02/2019/5c6999559a79474507b8e6e5 (и нет, измерение KPI — это не «централизованный указ на фальсификации»).
По-моему KPI — это просто прикрытие. Формальный повод. Примерно как гопники когда грабят просят вначале закурить или телефон позвонить. Ибо мне очень сложно представить почему на вскрытые нарушения центральная власть демонстративно закрывает глаза и раз за разом показывает что попавшихся с поличным трогать не будет.
У вашей ботофермы есть тысячи подтвержденных аккаунтов в госуслугах, со всеми положенными вещами вроде СНИЛС и ИНН?

tvrain.ru/teleshow/vechernee_shou/baev-510779
Вообще-то этот сюжет послужил поводом для того, что все зарегистрированные после 5 июня учетные записи не были допущены к голосованию (решение разовое, неудачное, и в будущем, конечно, регистрацию на mos.ru, для которой никакого подтверждения не требуется, использовать вряд ли будут). И да, для «ботофермы» это слишком дорого.
Там можно было даже в теории написать слово из трех букв в кодировке 1251. Но человек просто испортил бюллетень :-)
Из четырех букв даже, если null-terminated не обязательно делать. А еще можно было написать целых 24 буквы — и ничего тем самым не испортить!
Не, nonce это не считается как ответ. Плюс его видят все. А тут голос будет зашифрован
Это позволяет зафиксировать(и то без каких-либо гарантий) факт присутствия человека на участке, а не факт голосования.
Не хотели бы вас расстраивать, но урны для бюллетеней давно стоят открытые всем взглядам. Кабинок и ширм нет.

Так что видят, проголосовали вы или нет, тоже примерно все, а кто не видел — могут потом по записи с камер посмотреть.
Трудозатраты несопоставимы. Тем более, что на этом голосовании камеры работали только в последний день.

И в данном случае мне вообще странно, что все обсуждают это только с точки зрения закона (ПД это или нет). В наших реалиях это очевидный, рабочий и удобный инструмент для проверки того, проголосовал ли конкретный человек или нет. Без всяких сборов селфи с бюллетенем и т.д.

Более того, это дополнительно мотивирует сотрудника голосовать «да», даже если он против. Если они так легко узнали голосовал ли я, то они могут так же легко узнать как именно я проголосовал. Многие рисковать здесь точно не будут.

Т.е. такая возможность может быть даже полностью законной, но она напрямую влияет на то, кто у нас оказывается во власти.
Номер паспорта — это ПД, потому что так они определены в ФЗ-152 («персональные данные — любая информация, относящаяся к прямо или косвенно определенному или определяемому физическому лицу (субъекту персональных данных)»).

Ваш ник на этом ресурсе тоже косвенно относится к физическому лицу.
Еще раз — если я написал вот 10 цифр подряд в комментарии выше, означает ли это, что я разгласил чьи-то персональные данные?
Хватит спорить, а? Вы оба правы, на самом деле. Один номер паспорта — это персональные данные. И его разглашение, есть есть шансы узнать чей он — это большая проблема.

Однако если вы собираете вместе кучу этих номеров — то они, внезапно, становтся обезличенными персональными данными. Закон, в сущености, говорит об обезличивании как об альтернативе уничтожению.

Роскомнадзор чётко пишет о том, что при обработке обезличенных данных конфиденциальность не требуется.
если есть шансы узнать чей он

Вот именно. Если не приложить к нему соответствующую базу данных — шансы узнать хотя бы что-либо о человеке по одному лишь номеру паспорта равны нулю. Без нее номер паспорта — просто набор цифр, и сам по себе конфиденциальной информацией не является.
Как с этим согласуется судебное решение по поводу LinkedIn, объявившее куки и IP-адреса персональными данными?
В каком месте противоречие?
Я просто напомню официальный ответ Минкомсвязи: «Серии и номера паспортов перед загрузкой в приложение были закодированы и представляли собой полученную случайным образом последовательность знаков (хеш-сумма), не позволяющую идентифицировать гражданина. Хеш-суммы не являются персональными данными. Публикация такого случайного набора символов не может навредить гражданам»

Если бы публикация номеров паспортов открытым текстом не была противозаконной, то зачем бы они сочиняли эту ахинею про «полученную случайным образом последовательность знаков»? Написали бы просто «Публикация номеров паспортов не может навредить гражданам».

Их компетенция видна уже в этом:


Я просто напомню официальный ответ Минкомсвязи: «Серии и номера паспортов перед загрузкой в приложение были закодированы и представляли собой полученную случайным образом последовательность знаков (хеш-сумма), не позволяющую идентифицировать гражданина. Хеш-суммы не являются персональными данными. Публикация такого случайного набора символов не может навредить гражданам»


НИ РАЗУ НЕ СЛУЧАЙНЫМ, но важно, что НЕОБРАТИМЫМ и НЕ СОДЕРЖАЩИМ ИСХОДНЫЙ НАБОР данных

Ну почему, хеш функция должна получать на выходе неотличимые от случайных данные. И если исходные данные неизвестны, то и восстановить почти невозможно. Но это вообще про хеш функции, не в конкретном случае, когда данные известны и можно перебрать всё.
Не «необратимым», а «обратимым только перебором».
В данном случае это ключевой момент.

Хотя не исключаю, что для юридической чистоты достаточно, чтобы данные любым способом превращались в «непонятные значки», и даже base64 подошёл бы.

Да, правильное замечание.


base64 тоже "рандомизирует", ага ) tmin10

Нет, base64 это кодирование, не шифрование Т.е. применение хеширование было оправданным, но оно было применено неверно, что дало возможность восстановить исходную информацию.
Предположу, что если нужно, можно провести экспертизу, которая это зафиксирует для суда.

А шифрование — это не хэширование, шах и мат.


/под своей репликой я подразумеваю, что при шифровании НЕ ПРОИСХОДИТ потери информации, при хэшировании — ОЧЕНЬ ДАЖЕ происходит, читай про хэш-коллизии/

Ничего, что хэширование называют односторонним шифрованием?

Ничего, это не меняет сути того, что это разные процессы, с разными характеристиками и разными целями. Хотя если докапываться, то даже самое наличие какой-то информации является информацией (сорри за тавтологию).

Нет, base64 это кодирование, не шифрование

Вы уверены, что с точки зрения законов о хранении персональных данных есть какая-то разница между кодированием, хешированием и шифрованием?
В законе про это ничего нет, толкованием закона в конкретном случае должен заниматсья суд (если до него дойдёт) и экспертиза, которая сделает заключение по методам защиты ПД.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Этот вопрос интересует не только меня, но и весь наш отдел народного образования Отдела Народного Образования ©.
По идее это будет персональными данными, если с этими цифрами ещё как минимум фамилию приписать.
Номера паспортов неуникальные.
Номера паспортов неуникальные.
#даладно!
Из-за твоего коммента мне пришлось пойти перепроверить.
Сочетание серия-номер уникальное, номер — неуникальный.
Согласен. Просто отдельно номер паспорта практически нигде не используется. Везде связка серия+номер. Поэтому часто говорят «номер», подразумевают полный номер, который вместе с серией.
Неуникальность номера можно было и не проверять. 6 десятичных цифр при населении больше сотни миллионов. )
Тогда по идее нужна вторая БД, где хранятся уже полноценные персональные данные, где вбив серию+номер утекших паспортов некто сматчит проголосовавших с с этой БД.
Простите что???
Тут уже в комментах была ссылка на случай в Башкирии.

Это исключение, а не правило. Номера бланков паспортов должны быть уникальны. Но тем не менее возможность таких кейсов в системы надо закладывать. А то уже была история, когда я советский (условно) паспорт не мог в какое-то поле ввода засунуть, потому что эти идиоты сделали кривую валидацию ((((

Если он просто не принимается — то это ещё полбеды. А вот когда валидация разная в разных местах — это вообще «суши вёсла». У моего отца так до самой смерти и не смогли поменять номер паспорта в МТС. Ну ладно — у него он был второй и на последней старнице третьего, последнего (после 42 лет паспорт не меняется) стоял штамп. А если у кого-то он первый? Всё, номер будет потерян, потому что «эти идиоты» всё автоматизировали?
оффтопик

Сочувствую, вот оно лицо бездушной системы (((( которой на маленького человека плевать. Надеюсь, что в будущем все-таки разработчики будут думать головой, прежде чем что-то имплементировать.
Кстати, мне доставляет еще кучу "радости" задача интеграции разных источников. Я тут на днях получал очередную выписку из КБИ и офигел от того, что данные попросту не свести — каждый банк считает нужным вводить данные (адрес, паспорт, отделение выдачи и пр.) в своем уникальном формате, хотя казалось бы, что есть тот же ФИАС (в котором вроде как нет всех возможных адресов? тоже прокол), ну, и в том же духе.

Так зачем тогда вообще хешировать? Начал шифровать — шифруй хорошо. Даже если утечка ничем не грозит сегодня, завтра туда понадобиться добавить персональные данные и их добавят, при этом кто то бы закрыл уязвимость? Нет конечно.
Секьюрность нельзя «допилить потом», ее нужно закладывать изначально, чем больше времени проходит, тем тяжелей, что то исправить.
Этими данными можно обогатить другие базы, добавив признак «регистрировался в электронном голосовании».

А вот на этот случай в законе есть специальный пункт.


Не допускается объединение баз данных, содержащих персональные данные, обработка которых осуществляется в целях, несовместимых между собой.

Кто это сделает, тот и будет главным редиской с точки зрения закона.

Вот тоже подумалось — а что тут защищать? Безо всякого хеша берем случайное 4-значное число, берем случайное 6-значное число и получаем чью-то серию и номер паспорта.

Дальше можно писать разоблачительную статью о том, что сам принцип идентификации по паспорту не способен защитить и от утечки персональных данных (ну или какой-нибудь подобный бред).

Утечка — это когда полный набор паспортных данных однозначно привязывается к конкретному человеку (ФИО, кем и когда выдан, где зарегистрирован и т.п.). А не просто написать «6607 238764»

Так что все это напоминает обычный вброс на тему «у нас ничего не может быть сделано нормально».
habr.com/ru/post/356088
Одним из камней преткновения прошедшего заседания стало «хранение и сбор данных незарегистрированных пользователей». По мнению специалистов Роскомнадзора, социальная сеть Linkedin собирает подобные данные, а именно сведения об ip-адресах, браузере и файлы cookies. На эмоциональное возражение юристов Linkedin что эти данные не являются персональными, представитель Роскомнадзора ответил, что «это ваше мнение».

Необходимо напомнить, что согласно ФЗ-152 персональные данные — это любая информация, относящаяся к прямо или косвенно определенному или определяемому физическому лицу.

Значит, уникальный номер паспорта — не ПД, а ip, браузер и cookie незареганного юзера на linkedin — ПД, я все правильно понял?
Я бы не был однозначно уверен на тему ПД, учитывая очень широкую трактовку закона. Удобно, то что тебе надо — ПД, то что не надо — не ПД.
Это просто вы пока не знаете как использовать. С другой стороны можно взять другую бд от оператора связи, органов и уже получить какую-то информацию, скажем, вашу социальную активность. Ясно одно: никто наказан не будет, кроме тех кто раскопал эту бд. Авторы получат медали ;)

В частности, к числу идентификаторов (данных, позволяющих однозначно идентифицировать физическое лицо), которые сами по себе однозначно определяют физическое лицо, могут быть отнесены:
номер и серия паспорта...

Вот именно, что не «относятся», а «могут быть отнесены» (а могут и не быть отнесены).
В народе говорят, что «бьют по морде, а не по паспорту». Т.е. если номер и серия паспорта есть, а морды и ничего похожего нет, то…

Подскажите, пожалуйста, как узнать исходный адрес архива, где он располагался во время голосования и где сейчас можно найти сам архив. На чем основано предположение, что архив, лежащий на файлопомойке использовался именно так, как это описано в статье? Описанные алгоритмы работают в обе стороны. Сгенерировать такой файл можно за 5 минут.

Он по оригинальному адресу на госуслугах успел в web.archive.org засветиться.

Не поможете его там найти?

Saved 1 times 1 July.
...


Orange indicates that url was not found.


Есть ли ресурс, где снапшотят снапшотилку?

Так в статье же написано:
Https checkvoter.gosuslugi.ru degvoter.zip
Соответственно добавляете / и это становится реальным адресом. Затем идёте на сайт web.archive.org и через него получаете этот архив

Я туда сходил. Там ничего нет.

Спасибо

С вебархива уже выпилили:
«Sorry. This URL has been excluded from the Wayback Machine.»

Адовейший ад — это вставлять код скриншотами.

Каюсь, но какой смысл в том, чтобы это публиковать как код? :-)
Заголовок спойлера
private void checkButton_Click(object sender, EventArgs e)
    {
      if (this.passportTextbox.Text.Trim() == "")
      {
        int num1 = (int) MessageBox.Show("Введите серию и номер паспорта");
      }
      else
      {
        string rawData = this.passportTextbox.Text.Trim().Replace(" ", string.Empty);
        if (rawData.Length < 10)
        {
          this.textResult.Text = "Неверный формат серии или номера паспорта";
        }
        else
        {
          string commandText = string.Format("select * from passports where num='{0}' limit 1;", (object) Form1.ComputeSha256Hash(rawData));
          string connectionString = string.Format("Data Source=" + Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\db.sqlite");
          try
          {
            SQLiteConnection connection = new SQLiteConnection(connectionString);
            connection.Open();
            SQLiteDataAdapter sqLiteDataAdapter = new SQLiteDataAdapter(new SQLiteCommand(commandText, connection));
            DataTable dataTable1 = new DataTable();
            DataTable dataTable2 = dataTable1;
            sqLiteDataAdapter.Fill(dataTable2);
            if (dataTable1.Rows.Count > 0)
            {
              if (Convert.ToBoolean(dataTable1.Rows[0].ItemArray[1]))
                this.textResult.Text = "По паспорту «" + this.passportTextbox.Text + "» доступ к бюллетеню на дистанционном электронном голосовании ПРЕДОСТАВЛЕН";
              else
                this.textResult.Text = "По паспорту «" + this.passportTextbox.Text + "» доступ к бюллетеню на дистанционном электронном голосовании НЕ ПРЕДОСТАВЛЯЛСЯ";
            }
            else
              this.textResult.Text = "Паспорт «" + this.passportTextbox.Text + "» в списке участников дистанционного голосования НЕ НАЙДЕН";
            connection.Close();
          }
          catch (SQLiteException ex)
          {
            if (ex.ErrorCode != 1)
              return;
            int num2 = (int) MessageBox.Show("Файл db.sqlite не найден. Положите файл в папку вместе с exe.");
          }
        }
      }
    }

Юзабилити.


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

Вообще я когда писал статью, расчитывал, что человек возьмет и бинарник откроет в dotPeek. Копировать этот код не имея БД с хешами бессмысленно же

Я не буду открывать dotPeek. Мне нужно прочитать код на телефоне.
Вы анализируете проблему концентрируясь на деталях, которые служат лишь иллюстрацией. Хоть они и вторичны, но важны, как пример.
Первичная же проблема квалификации кадров. А это зависит от множества факторов. От "надо вчера", что классика в госслужбах, до банального недостатка бюджета.

Я тоже читаю с телефона. И со скриншота прочесть код было удобнее, чем сейчас текстом — он, по крайней мере, умещался по ширине экрана, хоть и стал от этого достаточно маленьким.

Я тоже читаю с телефона.

"— Доктор, помогите мне! Когда я делаю так (чешет левой рукой правое ухо), мне больно.
— Могу порекомендовать одно: не делайте так."

Всё правильно, автор поста задумывал так, чтобы никто и никогда не смог скопировать себе этот код)

Проще было бы вообще смс сервис для этих проверок запилить. И покрытие больше и фронт писать не надо.

Не надо никаких СМС. Просто надо грамотно писать бэкенды и понимать криптографию либо привлекать специалистов по ней.

Там и такой вариант был:
Следуя этой инструкции, члены УИК с помощью специальной программы, особым образом оформленных СМС-сообщений или звонка оператору колл-центра могли точно выяснить, записывался ли конкретный гражданин в интернет-избиратели и проголосовал ли он в итоге дистанционно. Проверить избирателя можно было по номеру его паспорта.

Но вот чего я не понял это как обновлялись данные. Это же программа только для проверки паспорта в слепке базы. После голосования результат что, сразу скидывался на сервер? Или в конце дня? Если в конце, то как защититься от нескольких голосований на разных участках по одному паспорту в течение дня? А если сразу, то зачем огород городить с локальными копиями вообще?
В Москве можно было записаться на онлайн-голосование. Далее в течение недели можно было проголосовать только один раз (как утверждается) на сайте. Но если вдруг человек передумал и решил проголосовать оффлайн, то ему давался только один день: 1 июля. Соответственно, это последний слепок, больше туда данные попадать не должны были.
Это же очень дорого. Но если денег девать некуда, то это тоже хорошее решение.

Разрабы лучше бы просто записали бы номера в текстовый файл без хешей и паролей — как прокомментировали выше, обезличенные номера паспорта персональными данными не являются, их можно нагенерировать миллионы, алгоритм у всех таких идентификаторов одинаковый: префикс + последовательность + контрольная сумма. Тогда бы у Медузы не было повода на этом похайпить. А так, кто-то проявил инициативу зашифровать, а теперь все изберкомы огребают.

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

Нет, знание самого факта того, что человек ходил голосовать, без информации как именно он проголосовал, не нарушает тайну голосования.
Даже если и так, знание людьми, что факт их голосования может быть проконтролирован напрямую влияет и на явку и на то, как именно люди голосуют.
Ну, на явку, предположим, влияет. С другой стороны, например, в Австралии, вообще по закону явка обязательна, но у меня не хватает фантазии придумать, как это влияет на результаты.
Одно дело если все обязаны голосовать на равных правах (хотя тоже не уверен что это хорошая практика), а другое дело, когда сгоняют во-первых только тех, кто и так больше за власть (бюджетники), а во-вторых с явным настоянием голосовать «за» (бюджетники не знают, что как проголосовали проверить невозможно). В итоге получаем неестественным путём полученные голоса «за».

Да и в отрыве за кого именно проголосовали. Больше явка — больше легитимность выборов. Если бы не фальсификации и не все эти полулегальные схемы по нагону явки — мы бы уже давно в другой стране жили.
Больше явка — больше легитимность выборов.
Ну так давайте продвигать идею обязательной явки, будет выше легитимность, и бюджетников будет бесполезно сгонять.

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

Доводите до абсурда. Хотя да, при всеобщем голосовании легитимность выше. Бюджетников всё равно будет смысл сгонять для подконтрольного голосования.

Вы людей совсем за идиотов-то не держите.

Ну извините. Если бы я подробно не изучал как работает электронное голосование — я бы тоже не знал. Вот меня посадили перед компьютером, предложили авторизоваться через госуслуги и поставить галочку. Откуда я знаю, что эта информация просто напрямую в базу не запишется? Иванов Иван Иванович, паспорт такой-то, проголосовал «против» в такое-то время. Многие голосовавшие даже текст поправок особо не смотрели, а вы хотите чтобы все в массе вникали в такие тонкости. Выборы — это же массовая штука. Масса на массу. Даже если какой-то процент разобрался — есть куча людей, которые не будут копать глубоко. А начальство и перспектива лишения премии — вот они, рядом. Многие это вообще просто как обязанность воспринимают. Проголосовал «за», всё, я молодец, выполнил поручение.
После завершения интернет-голосования, которое закончилось удивительно хорошо

Не согласен. В прошедшем голосовании есть минимум 2 проблемы, которые станут очевидны, если отвлечься от хешей и посмотреть на более общую ситуацию:


1) Эта программа позволяет на работе контролировать участие подчиненных в выборах и наказывать их за неучастие
2) У независимых наблюдателей нет никакой возможности проверить эти данные участников, что это реальные люди, что они по своей воле записались на голосование, а не "мертвые" души или боты тетушки в МФЦ, которая накупила сим-карт и зарегистрировала аккаунты на всех пенсионеров района.


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

Эта база вроде как позволяет определить не факт голосования, а факт взятия открпеительного, можно было и не голосовать? Так что 2 проблемы нет.
Если вы имели ввиду первую проблему, то это делается другим способом.
Каким?

Так а что там с распределением серий? Это тестовый набор или что?

Иное бы распределение было бы сильно удивительно, учитывая, что электронное голосование проходило только в двух субъектах федерации. Больше похоже, что автор статьи хотел реализовать какую-то интригу, но и о ней в статье не слова.

Это показывает, что в архиве не случайные номера паспортов, а из определенных регионов.
Что сходится с тем, что электронное голосование проводилось только в двух.

Поскольку SQLiteConnection реализует интерфейс IDisposable, то нужно было его оборачивать в using.


using (var connection = new SQLiteConnection(connectionString)) {

}

Вот все бы были такими умными, в 3 часа ночи, за 3 часа до дедлайна.
Далее, клиент-серверная архитектура вполне возможно не могла быть реализована в кратчайшие сроки чисто из за инфраструктурных проблем(вся бюрократия, для разворачивания нового кода в защищенном контуре).
И уже здесь в комментариях разгорелись споры, как правильно хэшировать такой набор данных. Очевидно, что типичный разработчик выдаст плюс минус изначальное решение.
Так что ещё хорошо, что не использовали просто гугл таблицы для хранения данных.
А если бы утекла база в plain text, то все бы хайпили, почему не могли захэшировать хотя бы с помощью sha256.


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

А кто-то заставлял тянуть до последнего? И про электронные участки, и про многодневное "голосование" — и, соответственно, необходимость такой проверки — было известно сильно заранее. Я, конечно, понимаю, что думать на шаг вперёд там никто не привык, поскольку все равно бестолку, завтра царь очередную радугу запретит и концепция поменяется, но всё же чуточку-то можно.

А никто не тянет до последнего. Просто издаётся указ из министерства сделать к завтра или через неделю, при этом на трудоемкость в министерстве никто смотреть не будет.
С очень большой вероятностью до конечного разработчика эта задача могла спуститься буквально за день/за часы до сдачи.

В бюджетных учреждениях в 90% случаях все так как вы описали. В лучшем случае программист который будет все делать получит все за день до сдачи а в худшем — дедлайн «уже вчера».
Разработчика тут никто и не винит. Речь как раз была в том, что виновато руководство, которое не привлекло ни архитектора ни безопасника. Если хотя бы один был привлечен — задача была бы решена без такого позора.
Т.е. завести поддомен на сайте госсулуги и разместить там общедоступный произвольный файл для скачивания можно, а развернуть там код, который загрузит в память csv-файл и будет отвечать true,false,null в зависимости от нахождения хэша и значения булевой переменной ну никак нельзя?
Вы знаете сколько времени потребуется C# разработчику чтобы написать такой серверный-бэкенд?
Там будет:
1. контроллер
2. фасад в котором будет один Dictionary<string,bool>, не нашел -> null, нашел -> вернул значение
3. Код загрузки csv

Это любой ASP.NET разработчик вам на собеседовании на листочке бумаги должен написать за гораздо меньшее время чем за 3 часа.

Что касается бюрократии — в государственных структурах когда «жопа горит» любые бюрократические проволочки решаются очень быстро. Просто в известность ставится вышестоящее начальство, которое решает проблемы бюрократии одним звонком.

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

Во-первых, вы так говорите «утечка», как будто хакеры вломились в закрытую систему и выкрали оттуда таблицу, а не скачали её с сайта госуслуг.
Во-вторых, это приложение не для выборов мисс Урюпинск, а для ОГ, на пиар которого потратили миллиарды — так что продукт-менеджер (если он вообще был) должен был учитывать повышенное внимание сообщества/журналистов.
Максимально приближёно к реальному «общероссийскому голосованию» (it-пеньки).
Очевидным требованием является то, что БД с хешами паспортов должна находиться на сервере

Наука давно доказала, что все аргументы, начинающиеся с «очевидно», являются демагогией.


Вы так лихо изволите писать это всё, как будто ТЗ видели, а не только результаты разработки.

Ничего наука не доказывала. Но мне запомнилась фраза моего преподавателя по алгебре: «очевидно, значит легко доказать». И, действительно, факт необходимости хранения бд на сервере легко доказать, — данные должны быть сокрыты от конечных пользователей, хотя бы потому, что это тайное голосование.

Тайна голосования распространяется на волеизъявление (в данном случае — «за» или «против»), но не на сам факт голосования.

Разве. По этим данным можно выяснить голосовал человек или нет. В последнем случае кто-то может подумать, что это протест (против уже принятых народом поправок), ну и т.д. и т.п. Конечно это важные данные, их нельзя сливать в сеть

Простите, Вы серьёзно сейчас мне доказываете утверждение доводом «кто-то может подумать»?

Ну, это так и работает. Вероятность мала, а последствия для определённого человека могут быть плачевными. Это как с вероятностью падения астероида на Землю, — было крайней степенью глупости не думать о способах предотвращения катастрофы заранее

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

Блин, УИК на вертолете должен в чуме оленевода проверить, не проголосовал ли он через интернет (прописка у него может московская была когда-то).
А данные на сервере.
1) Если определение ПД в законе рассматривать дословно, то пара (серия+номер паспорта)+(информация о том, что человек регистрировался на электронное голосование) — это действительно персональные данные. Кстати, насколько я понимаю, обратите внимание, что в базе речь идет не о тех, кто голосовал электронно, а о тех, кто регистрировался на электронное голосование.

2) Замедление вычислений для локальной базы ничего не дает. Через какое-то время ее вскроют и «утечка» все равно произойдет. С точки зрения закона никакой разницы.

3) Клиент-серверное приложение… Предложение для голосования, ну, так себе… Замечу, что это вообще-то было тестирование, которое в дальнейшем планируется распространять на всю страну. А страна большая и вот тут-то при клиент-серверном приложении ну просто с очень большой вероятностью возникнут косяки. И вот из-за таких косяков у граждан в некоторых локальных местах возникнут проблемы с реализацией избирательного права, закрепленного в Конституции. Т.е. в попытке ликвидации незначительного нарушения приватности (много ли можно вывести из того, что кто-то зарегистрировался для электронного голосования), мы можем легко влететь в нарушение избирательных прав.

PS В качестве решения навскидку видится только внесение изменений в законы о выборах или в сам закон о персональных данных, где явно прописать, что информация о способе голосования может быть открытой.
Еще решение — нагенерить левых номеров паспортов и добавить в базу.
Цифры номера паспортов сами по себе ничего не значат, но утечка текущей базы показывает, что:
  1. паспорт в базе принадлежат человеку. например, я не знаю, принадлежит ли номер 01 01 123456 хоть кому-нибудь, но если он найдется в текущей базе — то буду знать, а если в дополненной — все равно не буду
  2. этот человек проголосовал. Т.е. если в дополненной базе у сгенерированных паспортов будет указано, что часть из них проголосовали, то за шумом также не будет видно реальных данных.

Ну и как обычно, sqlite настолько терпимый, что позволяет писать говнокод в SQL и всё-равно работает :) Похоже на творение среднего студента, возможно он приходится сыном кому-то :)

Еще найденные ошибки:
1. Позволяем дублировать номера в БД — индекс не уникальный.
CREATE INDEX passports_i1 on passports(num)

Что позволяет нам получить интересную коллизию выдергивая записи запросом
select * from passports where num='{0}' limit 1;

Если есть две записи — с used 0 и с used 1, никто не гарантирует, что найдется именно запрещающая повторное голосование запись
1.1. Если считать номера паспортов не уникальными — тогда только номер паспорта, без даты выдачи хранить немного бесполезно.

2. SHA256 длиной в 256 бит, это 32 байта. Но мы старательно пихаем их в num varchar(10).
Sqlite всё стерпит :)
CREATE INDEX passports_i1 on passports(num)
CREATE TABLE passports(
   num varchar(10) not null,
   used integer not null check (used in (0,1))
)

Точно. С limit 1 — это серьезный косяк. Нужно или unique index сделать, или обработать случай, когда поиск выдаст больше 1 записи.

Уникальным является тип ДУЛ (Документ Удостоверяющий Личность) и его номер (в широком смысле слова — есть ДУЛ у которых только номер, есть где это будет комбинация из серии + номер — зависит от типа).

В данном случае у нас подразумевается единственный тип ДУЛ — «Паспорт РФ». И для него 10 символов серия+номер будут уникальными.

Там еще есть ряд признаков — дата выдачи, срок действия (для паспорта РФ срок действия привязан к дате рождения), признак недействительности (скажем, в случае подачи заявления об утере).

Так что тут все не так просто. И разбор маленького кусочка «говнокода», без знания как именно была поставлена задача, некорректен.

Например, при регистрации на онлайн голосование потребуется валидация паспорта. А тот ли это паспорт — совпадает ли серия номер с серией-номером того человека что регистрируется? А это вообще тот человек? Или кто-то взял бабушкин паспорт и по нему голосует? А это паспорт действителен? Не подавались ли на него заявления об утере?

Ну и так далее. Там проблем намного больше, чем способ хранения данных в базе.
НЛО прилетело и опубликовало эту надпись здесь
Уникальным является тип ДУЛ (Документ Удостоверяющий Личность) и его номер (в широком смысле слова — есть ДУЛ у которых только номер, есть где это будет комбинация из серии + номер — зависит от типа).
В данном случае у нас подразумевается единственный тип ДУЛ — «Паспорт РФ». И для него 10 символов серия+номер будут уникальными.

он ДОЛЖЕН быть уникальным, но это ошибка проектирования. В теории может быть два паспорта с одинаковыми номерами у двух разных людей — но это повод выкинуть exception и начать разбираться в ситуации, к тому же над исходными данными все равно у разработчиков приложения контроля нет, поэтому вешать UNIQUENESS на колонку с паспортом такое себе
Как минимум — я тут на Хабре читал истории про разных людей с одинаковыми номерами паспортов (именно кобминация серия+номер) и это не дело члена УИК определять валиден паспорт или нет.


А еще добавлю. Помимо паспорта можно проголосовать по временному удостоверению личности — это инфа 100%. Возможно как-то можно и по загранпаспорту или дип-паспорту. Так что множество вариантов резко растет )))

В теории может быть два паспорта с одинаковыми номерами у двух разных людей
Разве что один из них фальшивый. Полный номер паспорта (10 цифр) уникален. Бланков с одинаковыми номерами не выпускается.

Фальшивый? Вы ошибаетесь


https://pravo.ru/news/view/118167/ — например, хотя случай, конечно, из ряда вон выходящих

Бланков с одинаковыми номерами не выпускается.

Вы хотели сказать — "в идеальном мире". А в реальном — вот как-то так...

А давайте отвлечемся от критики (ее и так слишком много) и попробуем мыслить конструктивно. Ну раз мы тут все такие умные и все знаем — как бы вы решили эту задачу безопасно с точки зрения утечек?

Я не профессионал в криптографии, так, немножко теории и пара-тройка несложных задачек для внутреннего использования. Но основные положения таки помню:

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

2. Знание алгоритма шифрования не должно облегчать расшифровку. Т.е. криптостойкость основывается на сложности и уникальности ключа

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

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

Т.е. нужно или шифровать неким алгоритмом с использованием ключа, или хотя бы хешировать данные с подмешиванием этого ключа. Но ключ не должен быть связан с самими данными — мы не можем шифровать серию-номер паспорта, используя в качестве ключа, скажем, ФИО или данные по органу выдачи. Просто потому, что их можно получить из других источников и брутфорс будет выглядеть еще проще — берем базу паспортов (предполагается что она у нас есть ибо без нее данные по сериям-номерам это просто цифры, не имеющие привязки к конкретному субъекту и лишенные практического смысла) и считаем хеши по серии-номеру с подмешиванием, скажем ФИО.

Таким образом пришли к тому, что ключ должен быть оторван от данных. Что тут напрашивается? Самое простое — в момент регистрации субъект придумывает и вводит пароль. Который нигде не хранится, но используется в качестве ключа для шифрования (ну или подмешивания в хеш) серии-номера его паспорта для занесения в базу. При голосовании он опять вводит тот же пароль и система проверяет — зарегистрирован он для голосования, голосовал ли уже.

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

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

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

Такие вот мысли дилетанта.
как бы вы решили эту задачу безопасно с точки зрения утечек?

Приложение должно быть клиент-серверным. База данных не должна распространяться вместе с ним ни в каком виде, даже в надёжно зашифрованном.

PS. Правда если бы его делали такие же дилетанты, то безопасности базы это вообще не гарантирует. Такие вещи в любом случае должны делаться профессионалами. А тут, очевидно, либо наняли самых низкооплачиваемых работников на то, что осталось после распилов выделенного бабла, либо наоборот за кучу бабла наняли какого-нибудь ребенка депутата.
Я с вами полностью согласен, но. Утечку базы паспортов мы уже приняли за свершившийся факт. Без базы паспортов номера и серии ни о чем не говорят.

Так что мешает свершится факту утечки базы онлайн голосования с сервера?

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

Из того кусочка совершенно непонятно как происходит валидация паспорта. На каком этапе? Если задним числом, то мы не сможем зашифровать его по индивидуальному ключу…

В общем, вопросов больше чем ответов. И я, все-таки, призываю более конструктивно помыслить и попробовать нарисовать архитектуру системы от и до.
Так что мешает свершится факту утечки базы онлайн голосования с сервера?


Отсутствие такой базы на сервере?..

И я, все-таки, призываю более конструктивно помыслить и попробовать нарисовать архитектуру системы от и до.


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

p.s.: вот их уже порекомендовали комментом ниже habr.com/ru/company/analogbytes/blog/510512/#comment_21834556
Насколько медленный?

Вот допустим я взломщик. И мне в руки попала эта база. Что бы я сделал?

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

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

Далее, пара мощных компьютеров и на каждом несколько процессов/потоков для параллельной обработки.

Думаю, за недельку максимум выдал бы полный список паспортных данных (не только серии-номера) всех кто зарегистрировался и проголосовал онлайн.

В общем, тут без шифрования с уникальным ключом, никак не связанным с самими данными, не обойтись.

Или в принципе менять всю архитектуру так, чтобы такой базы не было в принципе, а работать напрямую с базой избирателей на защищенном сервере ЦИК
В общем, тут без шифрования с уникальным ключом, никак не связанным с самими данными, не обойтись.

Зашитого в прогу-проверяльщик?
Например 5 секунд для быстрого CPU, это будет для проверяющего 10-20 сек на любой офисной машинке, что вполне терпимо для той скорости, с которой выдают бюллетени.

Для перебора же это будет полтора года в один поток, что уже вполне неплохо.

> В общем, тут без шифрования с уникальным ключом, никак не связанным с самими данными, не обойтись.

Этот ключ надо как-то передать комиссиям на местам. Полагаю, что передаваться он будет тем же способом что и сама софтина. И утечка будет настолько же вероятна, так что толку от его добавления никакого не будет.

В теории, ЦИК знает, кто на какой участок должен прийти голосовать (по отрекпительным или прописке, других вариантов нет, если вы не карусельщик, но это уже не проблема криптографии). Следовало поделить базу по УИК-ам (или ТИК-ам), чтобы слив был не всего сразу, а хотя-бы только частей.
Например 5 секунд для быстрого CPU, это будет для проверяющего 10-20 сек на любой офисной машинке, что вполне терпимо для той скорости, с которой выдают бюллетени.


А теперь представим, что у злодея не офисная машинка, а нечто покруче. И не одна. И есть возможность запускать все это не в одном потоке, а в 30-ти… И это будет уже не полтора года, а в худшем случае месяц-два.

Те, кто занимаются подобными вещами, делают это на продажу, систематически и обладают весьма неплохой материальной базой и вычислительными ресурсами — это их хлеб.

Было дело, пытались втравить в какую-то блуду подобную. Вовремя почувствовал что что-то ту не то, что меня пытаются в темную использовать и соскочил.

Я уж не говорю о ситуации, когда не нужно всю базу проверять, а только конкретных людей с известными паспортными данными…

Этот ключ надо как-то передать комиссиям на местам. Полагаю, что передаваться он будет тем же способом что и сама софтина. И утечка будет настолько же вероятна, так что толку от его добавления никакого не будет.


Зачем? Списки по участкам формируются на основе некоторой базы. Вот в этой базе и нужно ставить отметку о том, что данный человек записался на электронное голосование и проголосовал электронно. И тогда он просто не должен попадать в список для оффлайн голосования.

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

Но чтобы рассуждать о постановке нужно бы знать «граничные условия» хотя бы. Какие требования были выставлены заказчиком. У нас это называется BRD — задание на разработку, бизнес-требования к продукту. По ним уже пишется FSD — ТЗ, по которому уже ведется разработка.

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

Если противник имеет неограниченные ресурсы, то никакая криптография не работает. Все криптографические алгоритмы можно «взломать» за конечное время. Хорошие криптографические алгоритмы нельзя взломать за разумное время. Поэтому увеличение сложности вычисления хэшфункции с различными ухищрениями по усложнению распараллеливания (как делает PBKDF2, например) — достаточно разумный вариант улучшения этой программы с сохранением архитектуры.
НЛО прилетело и опубликовало эту надпись здесь
Да, пожалуй погорячился. Чтобы «взломать» одноразовый блокнот нужно иметь какой-то критерий говорящий о том, что расшифрованные данные — те, что надо. Без этого… у вас на руках будет страшное количество равноценных вариантов cleartext'a. Но всё ещё за конечное время =)

Давайте посмотрим, какие ужасы мы имеем в части раскрытия перс. данных с точки зрения закона. Вот его основные положения:


  1. Сбор и обработка перс. данных должны осуществляться для заранее определенной цели.
  2. Запрещена обработка перс. данных для иных целей.
  3. Лица, получившие доступ к перс. данным, обязаны не раскрывать и не распространять.
  4. Обработке подлежат только те данные, которые отвечают целям.
  5. Гос. органы имеют право обрабатывать перс. данные.
  6. Запрещено объединять базы.

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


Еще можно усмотреть нарушение в том, что данные выложили на сайте, который проиндексировался и попал в веб-архивы. Однако сейчас данное нарушение, как минимум, устранено. Что оно вообще имело место, не так-то просто доказать.


Теперь давайте посмотрим, что в итоге получилось. Какое-то время на публичных ресурсах, возможно, лежали данные, из которых можно было узнать, что человек с таким-то номером паспорта принимал участие в голосовании. Однако ни об одном конкретном человеке данная информация раскрыта не была. А знаете, почему? Потому что как только какой-нибудь индивид напишет: "Я скачал файл degvoter.zip, распаковал с помощь johnripper, сопоставил с базой ФМС и узнал, что Татьяна Ларина записалась на голосование, но в нем не участвовала" — за этим героем сразу придут. Есть закон, который запрещает расшифровывать этот архив, объединять данные из этого архива с другими, распространять эти данные. И закон, как ни странно, работает. И именно закон защищает граждан, а не криптография.

Серия была в советских паспортах, деление на серию и номер было явно указано. В российских — просто номер. Что он разбит на группы, и группы что-то значат, не делает эти группы сериями.
Точно так же в номерах телефонов первая группа соответствует АТС, а у кредитных карт первые группы определяют Visa это или МИР. Но сериями их не называют.
Серия была в советских паспортах, деление на серию и номер было явно указано. В российских — просто номер. Что он разбит на группы, и группы что-то значат, не делает эти группы сериями.

Таки если бы вы потрудились почитать НПА, посвященные паспорту гражданина РФ. то не писали бы такой ерунды.

ПОСТАНОВЛЕНИЕ от 8 июля 1997 г. № 828
«ОБ УТВЕРЖДЕНИИ ПОЛОЖЕНИЯ О ПАСПОРТЕ ГРАЖДАНИНА РОССИЙСКОЙ ФЕДЕРАЦИИ, ОБРАЗЦА БЛАНКА И ОПИСАНИЯ ПАСПОРТА ГРАЖДАНИНА РОССИЙСКОЙ ФЕДЕРАЦИИ»

ОПИСАНИЕ БЛАНКА ПАСПОРТА ГРАЖДАНИНА РОССИЙСКОЙ ФЕДЕРАЦИИ
«3. Нумерация бланка паспорта состоит из 3 групп цифр. Первые 2 группы, состоящие из 4 цифр, обозначают серию бланка паспорта, третья группа, состоящая из 6 цифр, обозначает номер бланка паспорта»
Когда-то давно я потратил пару-тройку часов на этот вопрос: прочитал непосредственно «ПОЛОЖЕНИЕ О ПАСПОРТЕ ГРАЖДАНИНА РОССИЙСКОЙ ФЕДЕРАЦИИ», дальше действовал поиском… и ничего толком не нашёл.
Спасибо, благодаря вашей подсказке я узнал, что паспорт вообще не имеет ни номера, ни серии. Номер и серия у бланка, а не у паспорта
Очередная глупость. Паспортом бланк паспорта становится при заполнении.
Утилита для демонстрации возможности восстановления персональных данных DegvoterDecoder находится в репозитории, посвященном анализу данных голосования. По-умолчанию она настроена на 8 потоков. В случае если вы уже скачали архив degvoter.zip и вы программируете на C# – вы без труда разберетесь в принципе её работы.

Зачем так много кода?


echo 'select num from passports' | sqlite3 db.sqlite | sed -e 's/$/:/' > h.txt 
hashcat h.txt -m 1410 --force -a 3 '?d?d?d?d?d?d?d?d?d?d' --potfile-path test.pot -o formatted_out.txt -O
Hashcat — это вообще удар ниже пояса, особенно если у вас под рукой настольный компьютер с NVidia. К сожалению я был на даче и под рукой у меня был только ноутбук с встроенной графикой на которой OpenCL для hashcat работает не стабильно.
Hashcat — это вообще удар ниже пояса, особенно если у вас под рукой настольный компьютер с NVidia.

Да оно и на ноутбучном GPU интеля отработало минут за 15 :)


у меня был только ноутбук с встроенной графикой на которой OpenCL для hashcat работает не стабильно

Да, это уже как повезет. Тут — повезло. Некоторые режимы не очень работают, некоторые предыдущие версии вообще не запускались. Но поддержка интеля в hashcat с каждым годом все лучше и лучше.

Плохо, что автор статьи назвал программиста говнокодером. Потому что в ответ сам автор статьи может вполне заслуженно получить ярлык говнохакера или говноаналитега.
И вот почему.
Если на вход программисту даны следующие BRD ограничения:
1) Программа с базой должны быть stand alone
2) Интерфейс пользователя простой: вводит 10 цифр, получает инфу, участвовал гражданин в голосовании или нет

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

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

Можно было бы разместить БД на сервере, но это бы создало куда больший операционный риск, надеюсь, понятно, почему.

Если уж говорить о косяках интернет голосования в России, то, на мой взгляд, крупнейшим косяком является то, что для голосования достаточно было купить симку и персональные данные (полные персональные данные, а не только серию и номер паспорта) москвича, не зарегистрированного на госуслугах. Личного появления хотя бы на почте с паспортом для подтверждения своего эккаунта не требовалось.
Вы похоже не понимаете, что как происходит разработка ПО. Программисту всегда ставится бизнес-задача. Я напомню вам, что у нас на всех участках не то что есть Интернет, там даже обеспечено видео-наблюдение на инфраструктуре РосТелекома. Поэтому существующая инфраструктура УЖЕ работает с интернетом. Поэтому проблем не будет.

Но даже если предположить что вы правы и Интернет пропал везде, включая сотовые телефоны(!), то давайте подсчитаем по времени хеширования. Если просто добавить миллион итераций sha256, то проблему бы не заметили:
10 миллиардов комбинаций можно прогонять 4 часа (1 кратное выполнение хеша), а можно 400 лет. К тому времени данные бы потеряли актуальность. Цена реализации — дополнительный цикл for.
Поэтому существующая инфраструктура УЖЕ работает с интернетом. Поэтому проблем не будет.

Вам знаком такой термин: denial-of-service attack?
Так, там есть и защита на сетевом уровне DDoS, а RPS с одного IP нужно ограничить. Учитывая что паспортов всего миллион — хеши можно держать в памяти в словаре. Сможете сами оценить сколько запросов в секунду выдержит такая архитектура? Более того она еще и горизонтально масштабируемая :-)
Я к сожалению, не смогу дискутировать о DDoS атаках в деталях. У меня есть близкие знакомые, которые с этим работают плотно. Так вот, по их словам, атаки и защита постоянно совершенствуются. И новые изобретения атакующие любят демонстрировать во время каких-то серьезных мероприятий, типа выступления Путина.
Думаю, что голосование за/против поправок — тоже подходящая дата для демонстрации новых изобретений.
А что ддосить будем если все это внутри VPN? Гейт впн? А адрес откуда возьмем? Или всю сеть ростелекома будем пытаться положить? Дороговато выйдет уложить 2+ТБ/с ради того чтобы не дать проверить номер паспорта.
А адрес откуда возьмем?

давайте, я дам подсказку, и попробуйте ответить на свой вопрос самостоятельно.
Подсказка
30 июня источник «Медузы» прислал нам фотографию инструкции по проверке интернет-избирателей на голосовании по изменениям в Конституции РФ.
Ну ок, принимаю, допустим.

Вот более приближенный к реальной жизни вариант учитывая возможности ростелекома: Так как большая часть (если не все) УИКов и так подключены к сети ростелекома для целей видеонаблюдения за выборами — целевой сервис находится внутри сети ростелекома и маршрутизация настроена так что к сервису имеют доступ только УИКи.

Все, уронить сервис можно только уронив всю сеть ростелекома.
Если бы Ростелеком гарантировал стабильность работы, то ему и следовало бы поручить создание, на мой взгляд, совсем несложного сервиса проверки паспортов. Но этого сделано не было.
И претензии нужно предъявлять не к программисту, который в очень сжатые сроки состряпал то, что его попросили, а к организаторам электронного голосования.
Электронное голосование организованно, должен признать, непрофессионально, местами даже вопреки здравому смыслу. Хотя время на тщательное продумывание и изучение подводных камней (той же Эстонии, которая электронно голосует с 2007 года) — было.
Первый блин получился комом. Но, что-то получилось. Ничего страшного не произошло. И то хорошо.
Возможно, в будущем, руководить организацией электронного голосования поставят более компетентных людей.
Самый показательный факт — то, что обсуждаемая программа была предназначена для предотвращения повторного голосования (электронно + бумажно), но повторное голосование всё равно было возможным, так что единственным результатом её разработки и распространения стала публикация номеров паспортов всех участников электронного голосования.
Двойное голосование — это, разумеется, плохо, и с ним тоже нужно бороться, но если возможно только лишь двойное голосование (и невозможно проголосовать трижды), то это непринципиально: если вы уже имеете, скажем, 10% убеждённых сторонников, которые, все как один, готовы пойти и проголосовать так, как нужно вам, дважды — то с этим можно, условно говоря, и «на баррикады» идти.

P.S. А откуда, кстати, уверенность в том, что оба голоса зачтутся? Если информация о том, кто голосовал с помощью бумажки и ручки на сайт Госуслуг не передаётся, то логично было бы через сайт госулуг этот голос всё равно принимать — но не учитывать. Не знаю, правда, сдеалано это так сейчас или нет — но никакого другого разумного способа я представить себе, если честно, не могу.
если возможно только лишь двойное голосование (и невозможно проголосовать трижды), то это непринципиально

Тогда и эта программа незачем :^)

А откуда, кстати, уверенность в том, что оба голоса зачтутся?

Ни про один бумажный и ни про один электронный голос невозможно удостовериться, зачтутся они или нет. Такая вот система.
Ни про один бумажный и ни про один электронный голос невозможно удостовериться, зачтутся они или нет. Такая вот система.
Что не мешает, тем не менее, авторам статьи, на которую вы ссылаетесь, уверенно говорить о том, что это произойдёт.

Тогда и эта программа незачем :^)
Она не нужна для получения «достаточно качественных» итогов голосования — однако она нужна, чтобы «заткнуть рот» тем, кто будет рассказывать сказки о том, что от его имени уже проголосовали по почте. Потому что если таких вот, «за кого проголосовали бы по почте» было бы много — и уж их стоны в прессе мы бы видели.
P.S. А откуда, кстати, уверенность в том, что оба голоса зачтутся?

Если голосование — тайное, то — зачтутся. Другое дело, что к каждому проголосовавшему дважды (и это то как раз выяснить можно даже при тайном голосовании) можно применить меры административного характера за нарушение ФЗ О гарантии избирательных прав (или что-то вроде того).
rg.ru/2020/06/25/reg-cfo/popytka-progolosovat-dvazhdy-budet-schitatsia-narusheniem-zakona.html

Если голосование — тайное, то — зачтутся.
С какого перепугу? Что мешает хранить результаты голосования необработанными до тех пор, пока не закончится «бумажное» голосование, выкинуть проголосовавших на участках, а потом уже — сложить голоса всех оставшихся?

Другое дело, что к каждому проголосовавшему дважды (и это то как раз выяснить можно даже при тайном голосовании) можно применить меры административного характера за нарушение ФЗ О гарантии избирательных прав (или что-то вроде того).
rg.ru/2020/06/25/reg-cfo/popytka-progolosovat-dvazhdy-budet-schitatsia-narusheniem-zakona.html
Тоже, кстати, неплохой вариант.
Думаю, что как раз, программа была создана в ответ на подобные публикации (я читал нечто подобное не на bbc, а на дожде) — обратите внимание на хронологию. Поэтому все и получилось в такой спешке.
Так что, нет, не единственным. И еще раз повторю, что только номера паспортов — бесполезная информация.
Можно взять любое десятизначное число, с большой вероятностью, это будет чей-то номер паспорта.
Можно взять любое десятизначное число, с большой вероятностью, это будет чей-то номер паспорта.

Вероятность 109190337 / 10^10 = 1% — большая?
Подсек, признаю :)
Но если правильно считать вероятность в Москве, то учитывать нужно только номера, начинающиеся с 45, и из второй пары цифр исключить тех, кому нет еще 18. Повыше будет вероятность.
Номер паспорта состоит из кода региона, года и шестизначного номера. Этот тип паспорта действует 23 года. Получается 23 миллиона возможных номеров. Трудно сказать сколько человек получали паспорт в Москве, но вряд ли больше 10 миллионов. Часть из этих паспортов уже недействительна, т.о вероятность что случайное число окажется номером реального паспорта меньше 50%, скорее около 30. Но тоже неплохо
Нет. Если внимательно почитать ЦИКовские документы — то избирателям, записавшимся на ЭГ, но так и не «получившим доступ к электронному бюллетеню», возможность проголосовать на бумаге предоставлялась «в день голосования» — то есть 01.07 (электронное голосование шло до 30.06). Так что программа должна была быть сделана до этого срока.

Случай с Лобковым — ошибка УИК, участникам дистанционного голосования с 24 по 30.06 вообще не имели права выдавать бумажные бюллетени.
Случай с Лобковым — ошибка УИК, участникам дистанционного голосования с 24 по 30.06 вообще не имели права выдавать бумажные бюллетени.

Ну как бы да, но до Лобкова бумажный бюллетень получил Вайсенберг в другом УИК, а после Лобкова израильтянка Ильински дважды проголосовала бумажно впридачу к электронному голосованию, так что «ошибка УИК» совершалась повсеместно.
> израильтянка Ильински дважды проголосовала бумажно

Мне что-то кажется, что до израильских УИКов вообще не довели информацию об электронном голосовании.

> «ошибка УИК» совершалась повсеместно

Именно поэтому примерно в 12:00 24.06 информацию о том, что делать с электронно голосующими, до УИКов довели повторно.
Избиратели, проголосовавшие дважды — сознательные нарушители закона.
Технически проголосовать они могли дважды независимо то того, получили они доступ к электронному бюллетеню или нет.
В чем нарушение со стороны УИК? До 1 июля в УИК не было технической возможности проверки попыток злоупотреблений со стороны избирателей.
То, что Лобков продемонстрировал, что он может нарушить закон, не делает ему чести, а делает его преступником. Он мог бы еще продемонстрировать, что способен подрезать кошелек у какого-нибудь «лоха» в метро, поцарапать автомобиль на парковке или сделать еще какую-нибуль мерзость.
Если система голосования полагается на то, что все участники будут вести себя добросовестно, то она, очевидно, неприменима в РФ в 2020.
Я очень сомневаюсь, что Лобков единственный, кто «злоупотребил доверием» УИКа — он лишь единственный, кто сделал это под камеру.
> В чем нарушение со стороны УИК? До 1 июля в УИК не было технической возможности проверки попыток злоупотреблений со стороны избирателей.

Ошибаетесь. 24.06 УИКам были выданы списки открепившихся избирателей, в том числе участников ДЭГ. Многие УИКи не смогли/не захотели правильно организовать их обработку.
Вы все шутите:
24.06 УИКам были выданы списки открепившихся избирателей, в том числе участников ДЭГ. Многие УИКи не смогли/не захотели правильно организовать их обработку.

А кто бы смог?:
зампред Общественной палаты Москвы Алексей Венедиктов:

«Машина пропустила и по какой-то причине не вычеркнула Лобкова из книги избирателей на участковом избирательном участке. Может быть, есть еще такие люди. По моему представлению МГИК рассмотрел эту проблему и принял решение, что сейчас будут вручную проверены все списки на каждом участке. Все 1 млн 51 тысяча 155 человек, то есть весь регистр избирателей, записавшихся на дистанционное голосование», — сказал Венедиктов в четверг.


Раз так, то не надо было вообще придумывать всю эту ботву с электронным голосованием. Голосовали бы по старинке, зато надежно )


Взялся за гуж — не говори, что не дюж.

Вы никогда ошибок в жизни не делали в новых делах?
А если делали ошибки, больше никогда брались за то, что не получилось с первого раза? Просто называли то, что не получилось — ботвой, и занимались, тем, что получилось?
Олег за всё берётся смело…

Есть места, где ошибкам не место. Вот представляю себе Вас в атомной энергетике или авиации....

И…
Есть места, где ошибки не приводят к существенному ущербу, но подрывают и без того шаткое доверие к государственным институтам.
gecube: Вот представляю себе Вас в атомной энергетике или авиации....

Вы, кстати, сами чем занимаетесь?

Я надеюсь, не в авиации и не в атомной промышленности?

И знает ли работодатель о Вашем титаническом труде по созданию комментариев на интернет форумах?
Я надеюсь, не в авиации и не в атомной промышленности?

нет


И знает ли работодатель о Вашем титаническом труде по созданию комментариев на интернет форумах?

это Вас не касается, от слова совсем.


И, да, кстати, кто Вам сказал, что за эти аккаунтом не прячется ферма ботоводов из Ольгино, скажем ?

нет

Ну вот и славно.
это Вас не касается, от слова совсем.

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

А кто Вы там, ботовод или водобот, мне не интересно.

кто Вам сказал, что за эти аккаунтом не прячется ферма ботоводов из Ольгино, скажем ?

Кстати, да, признаков искусственного маркетинга у этой, в сущности, глупой статьи довольно много, начиная с того, по каким каналам я о ней узнал.
Ну и признаки того, что «за эти аккаунтом» прячется платный тролль – тоже есть. Только не из Ольгино, а скорее из «Operation Earnest Voice», ну или типа того.
Без всякого сомнения, печально, что Хабр уверенно заваливается в политику. Раньше, он вроде бы ее сторонился.
Ну и, конечно, хорошо, если тролли не работают на атомной станции, и плохо, что они все же часто работают администраторами в каком-нибудь интернет провадере. Вчера, к примеру, мой провайдер оставил без интернета на 8 часов пару сотен тысяч абонентов, возможно, из-за того, что какой-нибудь тролль, подрабатывающий на «Cambridge Analytica», создавал свой 5301 высер на каком-нибудь форуме, вместо того, чтобы выполнять свои функциональные обязанности.

Хабр сторонился политики, пока политики сторонились IT.
Вчера, к примеру, мой провайдер оставил без интернета на 8 часов пару сотен тысяч абонентов, возможно, из-за того, что какой-нибудь тролль, подрабатывающий на «Cambridge Analytica», создавал свой 5301 высер на каком-нибудь форуме, вместо того, чтобы выполнять свои функциональные обязанности.

Л — Логика. Как тролли и провайдеры связаны? Или веерные отключения этих ваших энторнетов — это обязательные признаки "демократических строев"? Или это политика "бей своих, чтобы чужие боялись"? Могу только пожалеть Вас

Логика троллям недоступна (а может, и не нужна) — такое встречается нередко.
На всякий случай, может и поймете: ит администраторы нередко подрабатывают троллями. и не только у провайдеров.
На этом все, дискуссия сия меня слегка утомила.
Вот представляю себе Вас в атомной энергетике
«Чернобыль помните? Ну вот… было такое дело...»
Вообще-то процедура, по моим сведениям, полностью аналогична бумажным открепительным (только их тут в три раза больше) — только на фоне скандала началось спихивание ответственнности, о чем нам и поведал Венедиктов.
Очевидным требованием является то, что БД с хешами паспортов должна находиться на сервере и это обязательно должно быть клиент-серверное приложение. Сразу же возникнет вопрос, а что делать если вдруг на участке сломается Интернет? Для этих целей нужно сделать Android-версию клиентского приложения, которую нужно также дать скачать членам УИК.

Ну чтобы не усложнять с интернетом — можно просто раздать оффлайновое приложение с блум фильтром и проинструктировать проверять на коллизии хоть по телефону голосом. Не идеально с криптографической точки зрения, но понимаю, что до правильных ZKP схем ДИТу как до луны.

ДИТ к этому приложению вообще никакого отношения не имеет.
Странно что вам никто не плюсанул за фильтр блума. Тут проблема в исполнителях — которые обязательно накосячат в ситуации с коллизией ))
Учитывая, что набор всех записавшихся на электронное голосование известен заранее, можно сделать такой блум-фильтр, чтобы коллизий среди них не было. При этом коллизии с теми, кто на электронное голосование не записывался, помешали бы восстановить номера паспортов, но не помешали бы работе избиркома.
Так речь не о записавшихся на ЭГ, а о записавшихся и проголосовавших (это что-то порядка 90% от записавшихся), этот список был неизвестен вплоть до конца электронного голосования.
Никак нет: это список записавшихся с флагом о том, проголосовал он или нет.
CREATE TABLE passports(
   num varchar(10) not null,
   used integer not null check (used in (0,1))
)
В таком случае тем же перебором можно было бы всё восстановить :-)
Нет, тут на мой взгляд оптимальное решение — клиент-серверное.
Учитывая что «внутри» инфраструктуру обеспечивает РосТелеком, а «снаружи» можно прикрутить резервный метод с ограниченным RPS.
С тем, что оптимальное решение — клиент-серверное, я не спорю; но по поводу блум-фильтра вы неправы :-)

На голосование зарегистрированы около 1млн человек из 10млрд возможных номеров паспортов, так что достаточно, чтобы в одну ячейку отображались порядка 10тыс возможных номеров паспортов. Предположим, номера 1234567890, 3133731337 и 3735941133 (и ещё 9997 других) все отображаются в одну ячейку; при этом лишь один из них будет соответствовать зарегистрированному участнику электронного голосования. Для УИК это не представит проблемы, потому что только один этот зарегистрированный номер и может проверяться; а вот переборщик не будет знать, который из 10тыс номеров имеется в виду.
потому что только один этот зарегистрированный номер и может проверяться
Нет, проверяются все пришедшие. Цель — определить, не проголосовал ли пришедший человек уже через электронное голосование. У вас же получается, что если человек с паспортом 1234567890 проголосовал электронно, то людям с паспортами 3133731337 и 3735941133 (и ещё 9997 другим) проголосовать не дадут.
Нет смысла проверять всех пришедших, потому что отметка о том, что человек зарегистрирован на электронное голосование (или откреплён на другой участок), у УИКа уже есть в бумажных списках.
Ну вот тут, хз. Я лично боюсь что исполнители накосячат или как-то не так применят неоднозначный механизм.
Перед этим голосованием я был в составе экспертной группы по голосованию в ДИТ и там было сделано всё хорошо (под это выделили и людские ресурсы и машинные и вообще удивительно, потому что на тестовом голосовании были проблемы). И после голосования также создалось впечатление что всё должно быть хорошо — и тут всплывает эта поделка, которая делалась другим ведомством в последний вечер :-D
Поэтому и не хочется видеть решения, которые допускают недетерминированное поведение. Это Россия, тут если исполнителю уже на этапе проектирования дали возможность налажать — он налажает
А мне кажется что тут можно было сделать очень простой добавочный механизм. Добавить солью в базу некий секретный идентификатор избирательного участка или идентификатор проверяльщика. Этот идентификатор вводится один раз в начале сеанса наподобии логина и потом проверяй сколько хочешь.
Таким образом были бы достигнуты 2 цели:
1) В случае утечки базы без соли расшифровать было бы сильно сложней и у соответствующих органов было бы доказательство откуда база слита
2) Зная что можно отследить откуда база взялась ее бы тщательней охраняли и уж точно добровольно не слили бы соль
Если рассуждать в сторону упрощения, то достаточно было по УИКам разослать Excel файлы с открытым перечнем проголосовавших номеров паспортов конкретного УИКа. Ничего нового в этом случае раскрыто бы не было. Потому что в бумажные журналы номера паспортов вносятся вручную без всякого хеширования и видны каждому входящему на голосование гражданину.
Ну а проверка, соответственно, по Ctrl+F :)
Причём, для SQLite имеется SEE. www.sqlite.org/see/doc/release/www/readme.wiki Впрочем, даже об этом в ЦИКе подумать было некому.

Кстати, мне не понравилось, как сделано в SEE. И я придумал схему «произвольный доступ к зашифрованному файлу». По сравнению с OFB значительно повышает скорость поиска именно для такой задачи.
«люди-снежинки» — вежливый и дипломатичный способ писать слово «руко(мяу)ы». вдруг, кому было интересно.

а по сабжу — с какого эти данные, вообще, куда-то двигались? давайте наплодим сущностей, давайте у нас будет много копий одних и тех же данных… н(мяу)й 152й ФЗ, никто же не будет против, а нам так проще…

а еще, ну, типа, эти данные могли быть, как бы, не в процессе онлайн-голосования собраться, а «перед» голосованием. в плане, если предположить, что, допустим, просто предположим, что они есиа использовали нормально, межведомственные спецификации тоже не требуют «копий перс. данных много раз» и они их соблюдали…
в таком случае, откуда еще могли взяться большие списки паспортных данных людей с контексте онлайн-голосований? для какой цели? почему эта цель требовала выносить эти данные наружу? почему многих все кому не лень задолбали звонками, уточняющими, за кого будете голосовать и будете ли? ну и, какие «действия» эффективнее производить, если взять кучу данных, раздербанить их по гео-привязке или еще каким критериям, чтобы раздать куче разных команд прорабатывать (не одно, а несколько действий над единицей данных (персоной)) и «поштучно» этих самых исполнителей «мотивировать»?

как бы, может же быть так, что данные уплыли просто потому, что для выполнения «неких задач неоффициального характера» им просто необходимо было уплыть?

такие дела. а когда встречаются эти два фактора: рас(мяу)яйство и «второй», то, мне кажется, странно было бы, если бы утечек не было.

а Минкомсвязь, не исключено, может быть, даже и имеет причины честно говорить, что утечки с ними не связаны… ну, потому что с ними они, действительно" не связаны, а могли произойти «как-то еще»

а еще, ну, у МФО и их агрегаторов можно, думаю, разжиться довольно подробными и довольно незащищенными данными, вообще не связанными с есиа… дальше удалить устаревшие паспорта, если нужно, как-то (я не знаю точно как, но, почти уверен, есть способ проверять есть ли человек в госуслугах (может, восстановление пароля или какой-нибудь/чей-небудь рабочий интерфейс, короче, это реально)
а дальше уже с этими данными работать, выяснять, идут/не идут голосовать, будут ли голосовать онлайн, а если нет, то, вот он, чистый бюллетень, считай.

короче, в сабже написано все здраво, я не спорю, однако, думаю, что архивы с данными образуются, обычно, по двум причинам: если их массово вгружают, либо если их массово выгружают. в первом случае, данные извне могли вливаться в «туда» и «дополнять картину», во втором случае, для чего-то их выгружают, чтобы дальше как-то использовать (выше тоже описывал вариант)

другой причины, кроме идиотизма, рас(мяу)яства, недосыпа и… ну, костылей (не успели нормально подключить, подключим так, там несколько дней, кто заметит), как мне кажется, делать бэкап всей базы перс.данных, ну, типа, просто нету.

пардон за «слог», я сильно сонный.

Номер паспорта это код города + год + порядковый номер бланка.
Могу ошибаться, но кодов города 90, а не 100, количество лет с 91 года по 2020 — 29. Перебор можно начинать с наименьшего и менять сначала код города и год, а только потом порядковый номер. Таким образом мы сможем не вычислять лишние порядковые номера когда найдём хэши всех паспортов.
Т.е. это никакие не 10^10, это в худшем случае 90 x 29 x 10^6, а скорее всего значительно меньше

количество лет с 91 года по 2020 — 29

Российские паспорта начали выдавать с 1997.

"Для этих целей нужно сделать Android-версию клиентского приложения, которую нужно также дать скачать членам УИК."
Как-то непонятно, как это спасет. Учитывая, что последние версии Android'а всячески противодействуют отправке СМС приложениями

На телефоне есть мобильный интернет. Зачем слать СМС?
Доверие зависит от степени соблюдения оговорённых правил, а также от умения правильно действовать для достижения поставленных целей. (с) Википедия
Тут предлагают как бы защитить эти данные, но я предложу вообще их не защищать. Зачем скрывать от кого-то кто проголосовал? Эти данные наоборот должны быть открыты для всех. Я хочу быть абсолютно уверен что мой паспортный номер не голосовал и в случае чего хочу чтоб это можно было подтвердить публично несколькими источниками.
Это вы сейчас хотите. Как только появится официальная база и официальные же требования по приёму на работу, где за приём «аполитичных» людей на работу будут накладываться штрафы… вы немедленно захотите обратного.
Я хочу быть абсолютно уверен что мой паспортный номер не голосовал и в случае чего хочу чтоб это можно было подтвердить публично несколькими источниками.

вы не этого хотите. Вы хотите способ проверки для себя лично любимого с прозрачным алгоритмом под капотом. Т.е. тот самый блокчейн с ключами шифровки-дешифровки )
Парадоксально, но факт — у государства все равно имеется возможность узнать проголосовал ли произвольный Вася Пупкин, т.к. все бланки наличествуют в [У|Т|Ц]ИКах. По крайней мере хотя бы определенное время. Скорее всего должна существовать процедура уничтожения этих реестров, после проведения голосования, но дальше можете поразмышлять — действительно ли они будут соблюдаться ) Поэтому скорее проблема только лишь в том, КТО именно имеет доступ к этим данным


Ну, либо пора признавать, что хватит уже играть в демократию и тайное голосование и переходить к новым способам управления и высказывания своего мнения (развожу руками)

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

Ну, пускай будет гит, а не блокчейн — каждый последующий голос верифицирован предыдущим. В SQLite же попросту можно сделать UPDATE на любую строчку с результатом голосования и сама база никак не поможет это отследить. Можно поверх навертеть всякое, но такое себе (просто мы сравниваем сущности разного порядка).

Что мешает ЦИКу перед оглашением итогов заменить весь блокчейн или весь гит-репозиторий целиком? Это ненамного сложнее, чем UPDATE в SQLite.
Но ещё проще сразу писать в блокчейн или в гит-репозиторий «исправленный» голос, тогда потом не нужна будет ни замена ни UPDATE. И как это отследить?

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


Но ещё проще сразу писать в блокчейн или в гит-репозиторий «исправленный» голос, тогда потом не нужна будет ни замена ни UPDATE. И как это отследить?

нужен прозрачный алгоритм работы всей системы, а не система по образу черного ящика. Я считаю, что это возможно. Остается только реализовать.

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

Возможность проверки SQLite-таблицы в любой момент времени с начала голосования точно так же защитила бы от UPDATE. Так что даёт блокчейн?
Возможность проверки SQLite-таблицы в любой момент времени с начала голосования точно так же защитила бы от UPDATE.

Сама база — не защитила бы. Т.е. защитил бы access/update log (да и то на самом деле нет — т.к. модификация могла идти мимо штатных API базы, а, например, через файлы на диске или прямое редактирование ОЗУ), но кто в него будет смотреть?
А сама структура цепочки или дерева хэшей позволяет именно, что сделать append only структуру. ОКей, Вы можете взять SQLite и обложить его кучей хэш-сум, но в одном из вариантов Вы просто построите блокчейн опять же, просто в качестве хранилища будет SQLite )


Еще раз — смысл блокчейна для голосования в том, что нельзя подделать "задним числом" все те голоса, которые в него попали. Ну, и сам по себе он не очень ценен — нужна нормальная обертка вокруг этого всего, чтобы любой мог проверить свой голос.

Зачем логи, зачем хэши? Сравнить две версии базы на то, не изменилось ли значение поля у ранее существовавших записей — тривиальный SQL-запрос.

Вам точно так же придётся всё время проверять блокчейн, чтобы его не заменили целиком.
Сравнить две версии базы на то, не изменилось ли значение поля у ранее существовавших записей — тривиальный SQL-запрос.

ага, только нюанс в том, что Вы не можете в базе держать "голые" данные. Голос должен быть прочитан пользователем, которому он принадлежит, и ИК (ну, ок, самой системой) в автоматизированном режиме. При условии доступа к базе это шифрование, причем с хитрыми ключами (схема Шамира?). А если доступа к базе нет (что более вероятно) — нужен нормальный API и вся магия будет в нем (авторизация, контроль доступа, все эти проверки и прочее). И здесь как будто уже вообще сложнее

Хорошо; а блокчейн тут как поможет?

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


Блокче́йн (англ. blockchain[1], изначально block chain[2]) — выстроенная по определённым правилам непрерывная последовательная цепочка блоков (связный список), содержащих информацию. Связь между блоками обеспечивается не только нумерацией, но и тем, что каждый блок содержит свою собственную хеш-сумму и хеш-сумму предыдущего блока. Для изменения информации в блоке придётся редактировать и все последующие блоки. Чаще всего копии цепочек блоков хранятся на множестве разных компьютеров независимо друг от друга. Это делает крайне затруднительным внесение изменений в информацию, уже включённую в блоки[3].

Т.е. из этого определения можно сделать вывод, что суть БЧ — всего лишь определенная структура данных. Не более. Ее физическое представление может быть каким угодным — файлы, БД, что угодно. Вторая вещь — блокчейн предоставляет определенные механизмы, те же "смарт-контракты", распространяя свое определение с самих структур данных на способ работы с ним (и по сути затрагивая часть АПИ). Вот с помощью этих самых контрактов и можно обеспечить проверки вроде "имеет ли право избиратель ХХХ голосовать", запись голосов и прочее, но это не имеет особого значения.


Касательно того, что можно обойтись без БЧ — да, можно, если все грамотно спроектировать, но это тоже самое, что изобретать автомобиль с нуля, если можно взять готовый чертеж :-/

Это все понятно.
Так вопрос то к вам простой, что даёт блокчейн в этом случае? Защита от подмены таблицы такая же, как от подмены блокчейна. Всегда можно сделать UPDATE в одной и REBASE в другом. Мы же централизованному хранителю не доверяем. И хоть облейся контрактами, от ребейза не сбежать.
Мы же централизованному хранителю не доверяем.

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


Единственное, что меня смущает, как и Вас — как построить алгоритм подсчета и верификации так, чтобы в сами результаты попали результаты, а не форкнутый БЧ )
Т.е. как Вы и говорите — наружу показываем, что у нас все хорошо, человек голосовал или не голосовал ровно так, как он это сделал, а внутри сделали магию )
Поэтому у наблюдателей должен быть отдельный ключ для вытаскивания результатов голосования (uuid избирателя они вытащить не могут, только если обезличенный) и возможности посчитать общую сумму. И сравнения ее с официальными данными.
Учитывая, что все эти вопросы возникают — очевидно, что разработка нормальной прозрачной системы голосования — это задача не на вечер и не на два. И тут нужно нормальное проектирование высококвалифицированными специалистами, а не тяп ляп.

Ну чисто теоретически по электронному голосованию должен-же составляться какой-то «бумажный» бюлетень с результатми голосования, который потом попадает куда-то в общий бюлетень голосования. Так что не вижу разницы проверить бюлетень электронного голосования или какого-то конкретного УИК, по идее наблюдатели должны это мочь.

Какой-то странный флоу. Делаем электронное голосование. Печатаем общий результат. Подписываем. Вносим в систему ГАС Выборы. Может сразу вносить, без промежуточной бумаги? А то так дойдешь и то дого, что на каждый электронный голос в реальную урну какого-то гипотетического УИКа "для электронного голосования" должны были вкидывать реально напечатанный бюллетень?

Ну «бумажный» не зря написан в кавычках. Имеется в виду некий документ определенного образца который по идее для электронного голосования не должен отличаться от документа любого другого УИКа. Я не знаю как там все это реально происходит. Просто мои предположения. Я просто не вижу проблемы с «подменой блкчейна». Есть публичный блокчейн, есть официальны бюлетень результатов цифрового голосования. Зачем подменять блокчейн, если общий результат все равно можно проверить…
Зачем подменять блокчейн, если общий результат все равно можно проверить…

Эм, какое-то странное допущение. Потому что приписки и описки в бумажных протоколах — сплошь и рядом. И как Вы проверите, что в бумажный протокол внесли именно ТОТ блокчейн?

Вы ещё спросите, зачем в КОИБ совать бумажный бюллетень, если можно просто кнопку нажимать

Чтобы потом вручную можно было проверить подсчет КОИБа? /что вряд ли будут делать, ибо зачем тратить силы?/ Хотя, да, действительно — какая-то половинчатая мера )))

На самом деле — нет, не составляется: результаты электронно проголосовавших включаются в протоколы тех УИКов, к которым проголосовавшие прикреплены.
Если так, то наблюдатели должны иметь возможность поверить, что количество электронных голосов для этого УИКа соответсвует «публичному блокчейну». Опять-же как тут можно подменить блокчейн не совсем понятно, хотя тут поле для манипуляций уже немного больше конечно… Лучше бы считали как отдельный УИК.
Лучше бы считали как отдельный УИК.

Этому мешает закон, который запрещает к одному УИК прикреплять больше 3000 избирателей.
Нет. Буковки ТИК ДЭГ вам ничего не говорят?
> результаты электронно проголосовавших включаются в протоколы тех УИКов, к которым проголосовавшие прикреплены

Кстати, это еще и невозможно в текущей системе ДЭГ — номер УИКа, к которому прикреплен проголосовавший, в системе подсчета голосов не участвует.
> вы не этого хотите. Вы хотите способ проверки для себя лично любимого с прозрачным алгоритмом под капотом.

Нет, я хочу именно открытых данных. Чтоб и я сам, и любой другой (независимые организации) мог проверить кто, когда и сколько голосовал. Нет ни одной причины это скрывать. Как сейчас с моим ИНН любой может узнать сколько я должен налоговой, но вот почему-то как речь заходит про голосование тут вдруг идут тайны и шифрования, да такие что даже я сам про себя ничего не знаю и почему-то не удивлюсь, что делается это лишь для того чтоб я мог проголосовать за поправки в двух регионах просто пока спал.
… привлекайте архитектора
… привлекайте разработчика с опытом/образованием в сфере криптографии или информационной безопасности
Кто б спорил, но…
Архитектура на коленке
Предположим, что у нас вообще нет времени и надо написать решение в течении ночи....
Это, как бы, ясно, не тот пример, который можно предложить для подражания.
Сервер работает только по HTTPS и только во время голосования и имеет ограничение в 1 RPS с IP.
Если HTTPS с аутентификацией клиента, то зачем 1 RPS? А если без аутентификации, то 1 RPS не поможет. Во-первых, неявное предположение об уникальности IP у всех членов избиркома — ложно. Во-вторых, нарушитель может использовать достаточное большое количество адресов, как для обращений, так и для нарушения работы этого сервиса.
… скорость вычисления хэша должна быть несколько единиц в секунду.
Хм, во-первых, где? На самом тормозном Андройд? Или где-то ещё? Во-вторых, а смысл, если проверка данных доступна только по защищённому каналу к сервису с 1 RPS? ;)
… Если есть только база, то без известного метода хеширования восстановить что-то будет невозможно...
Это ж, да! Это ж один из самых популярных способов защиты, но…
… окажется на порядок более защищенным чем ...
Совсем неясно, одно из двух, либо задание на безопасность выполнено (т.е. такой-то и сякой-то нарушитель может сделать то-то и это-то только с некой, достаточно малой, вероятностью), либо нет.

P.S.
Кстати, так и какие у потенциального нарушителя цели? Список действительных номеров паспортов РФ? Так, скажем, МВД не считает их персональными данными и раздаёт сервис по проверке номера широкому кругу лиц.

P.P.S.
А «Медуза» всё равно ж, тот или иной, яркий заголовок придумала бы, это ж их работа ж…
Как справедливо отметили ранее, передавать полную копию базы всем клиентам не очень хорошее архитектурное решение. Но представим, что изменения в регламент были внесены 'по ходу пьесы' и менеджмент проекта отрапортовал о готовности системы высокому начальству не считаясь с реальным положением дел (тем более что рапортовать могли одни менеджеры, а отвечать за техническую реализация другие).

Таким образом, «техзадание» непосредственным исполнителям получилось примерно такое:

  1. 30 июня около 22:00 МСК
  2. В наличие файл (exel или csv) с двумя полями: номер паспорта (некоторые номера дублированы) и отметка о голосовании
  3. Доступные серверные мощности — место для файла на 'госуслугах'
  4. Члены УИК технически не очень грамотные пользователи
  5. Решение должно быть готово к 7:00 1 июля

То что получилось на выходе — известно.

Вопрос:
Как сделать по этому же ТЗ приложение, которое дотошные журналисты (или просто пентестеры) не опозорят через неделю?
Слабым местом системы по сути является сам номер паспорта — не очень длинный, с маленьким алфавитом и хорошо известными правилами формирования.

На первый взгляд, возможны 10^10, т.е. 10 миллиардов вариантов. Но, т.к. паспорта текущего образца выдаются с 1997, а регионов в ОКАТО 83, получается меньше двух миллиардов (а если аккуратно исключить Крым и Севастополь до 2014 года, то еще меньше) номеров. Негусто.
Дополнительно известно, что всего на электронное голосование зарегистрировалось около миллиона человек.

Возможное решение
К каждому номеру паспорта генерируем достаточно длинный (64 латинских символа, например ) случайный дополнительный код: соль. Хеш от конкатенации кладем в одно поле БД, соль в другое поле БД, отметку о прохождении голосования в третье поле. Приложение и базу складываем в архив и помещаем на сервер из п.3 ТЗ.

Дальше следим за руками
Приложение получает номер паспорта и считает хеш от каждой соли по очереди до тех пор, пока не найдет совпадение в базе (максимум миллион раз). Если совпадение не найдено, то выдаем сообщение «паспорт не найден в списке участников дистанционного голосования», если найдено, то значение поля отметки о прохождении голосования. Поиск займет несколько больше, чем в оригинальном приложении, но вполне допустимое время.

Мой наколеночный код на Python с использованием стандартной библиотеки hashlib на CPU Intel Core i7 в один поток с предварительно загруженной в память БД считает около 800 тысяч хешей в секунду. Таким образом проверка одного номера паспорта занимает в среднем около 1 секунды.

С другой стороны, что бы брутфорснуть полный список номеров паспортов нужно посчитать порядка 10^15 ( (2*10^9)/2 * 10^6) хешей, т.е. при прочих равных условиях в миллиард раз больше времени. В один поток на Core i7 — около 30 лет.

Зная, что голосование проходило только в Москве и Нижнем Новгороде можно в первую очередь проверять номера паспортов этих регионов, что даст бОльшую часть данных. При таком подходе нужно будет посчитать в районе 2.3*10^14 хешей. При той же вычислительной мощности — около 300 дней.

В любом случае это значительно больше, чем неделя, которая понадобилась «Медузе».
Зная, что голосование проходило только в Москве и Нижнем Новгороде можно в первую очередь проверять номера паспортов этих регионов, что даст бОльшую часть данных.

этот вывод не выдерживает никакой критики. То что человек зарегистрирован в МСК или НН (или хотя бы голосует в МСК или НН) совершенно не означает, что он получал паспорт в МСК или НН, учитывая


  1. Количество «понаехавших» в МСК
  2. Срок действия паспорта
КДПВ показывает, что предположение здравое.
Строго говоря, регионы и годы нужно ранжировать по предполагаемой вероятности попадания их номеров в список. Предположить, что значительная часть паспортов была выдана в Москве — разумно даже не потому что голосование проходило в Москве, а потому что Москва очень населенный регион. А например паспорта, выданные в Ненецком автономном округе искать вообще смысла нет, потому что его население всего 44 тысячи человек, т.е. около 2% от теоретически возможного кол-ва. Эти паспорта в любой выборке, не связанной с этим субъектом будут очень редкими.
Аналогично можно ранжировать года. Стоит ожидать, что паспортов выданных 20 и более лет назад будет меньше из-за регламентной замены и утери. А паспортов выданных менее 4 лет назад из-за того что большой части их получателей еще нет 18 лет.
2/3 (на самом деле чуть-чуть не так, но лень половозрастную статистику смотреть) владельцев паспортов, выданных менее 4 лет назад — люди в возрасте 20-24 и 45-49 лет, так что особо отбрасывать их не стоит.
Не отбрасывать, а ранжировать. Искать номера из этих годов после более вероятных

Не стоило бы потратить усилия по созданию этой эвристики на более адекватные алгоритмы для дистанционного голосования?
Ну, то есть я не спорю с тем, что эвристика — это круто. Но лучше железобетонные алгоритмы.
И еще что думаете по этому поводу?

Кажется вы подозреваете, что я имею к этой истории какое-то отношение. Это не так. Я даже воздухом не дышу не живу в РФ.
Мое мнение (но это уже политика), что вообще не стоило тратить усилия на это мероприятие.
Мой коммент не более, чем мысленный эксперимент, который мы с ребенком проделали в качестве разминки. Постановка задачи — как улучшить параметры системы в гипотетически заданных условиях. Опять же полезно будет если коллективный разум найдет ошибки.
Он собирается писать годовую работу по теме организации электронного голосования и мы на этом примере рассматривали кейс «как делать нельзя».
А господам которые всю эту грусть написали я бы и ... не доверил
потому что его население всего 44 тысячи человек, т.е. около 2% от теоретически возможного кол-ва

По-моему, 0.2% (от 23 млн возможных).
Точно, в порядке ошибся
В 22:17 по МСК уже приложение было скомпилировано, в 22:38 был дописан файл ReadMe.txt. Доступных серверных мощностей под ДЭГ чуть более чем дохера. Там одних виртуалок было около 150 штук.
Проблема была в том, что эту поделку, оказывается делал даже не ДИТ Москвы, а совсем другое ведомство
Наверное вы абсолютно правы. И времени было больше и серверные мощности в избытке.
Только времени все равно недостаточно, а мощностями управляет другой департамент.
И вообще, вся эта история скорее про менеджмент, чем про разработку.
Как сделать по этому же ТЗ приложение, которое дотошные журналисты (или просто пентестеры) не опозорят через неделю?
  1. Хранить номера паспортов открытым текстом;
  2. Выложить приложение в открытый доступ;
  3. Выпустить пресс-релиз, в котором объяснить, что обезличенные номера паспортов не являются персональными данными, и их публикация не может навредить гражданам.

При таком раскладе нечего взламывать, нечему утекать, и не может быть повода для позора.
Тоже да. Но это совсем другой паттерн целеполагания/проектирования/разработки.
Так-то весь регламент работы и исходный код системы нужно было опубликовать за полгода-год до использования, обсудить, найти уязвимости, исправить. Повторить начиная с п.1 до полной готовности продукта.
Конкретно три этих пункта вполне можно было выполнить за девять часов, отведённых на разработку. Но они, естественно, не были в компетенции программиста, которому поручили реализацию кривого ТЗ.

Я в целом к тому, что организационные проблемы решаются организационными методами, а не техническими.
Выпустить пресс-релиз, в котором объяснить, что обезличенные номера паспортов не являются персональными данными, и их публикация не может навредить гражданам.
Ну вы же понимаете, что это бесполезно? Люди, способные размышлять — и так об этом знают. А люди, поднимающие шумиху в прессе — всё равно будут орать, как будто их режут.

Извините, но Вы неправы. Причем по всем пунктам. Единственное, с чем могу согласиться, что журналисты зачастую в погоне за скандальным заголовком и кликбейтом дуют на воду или раздувают пожар из ничего, но иногда они реально затрагивают важные темы. Касательно номеров паспортов — давайте определимся с тем является ли эта информация ценной или нет. Т.к. наличие базы данных паспортов в одном месте реально дает СПИСОК ДЕЙСТВУЮЩИХ (или около того) паспортов. Эту базу как-то можно использовать в своих целях? Ну, например, в целях подделки паспортов? Или еще какого-нибудь мошенничества? Скорее да, чем нет. А тот же сервис МВД по проверке паспортов должен быть защищен от перебора злоумышленником и взлома. Ценна ли информация, что некий гражданин с паспортом ХХУУНННННН голосовал электронно? Возможно. А возможно, что и нет. Но с привязкой к геолокациии (ура, москвичи), с привязкой к другим данным — это дает отдельные дополнительные векторы атаки и давления на граждан. Это несомненно. С другой стороны, прекрасно очевидно, что государственные структуры и так имеют доступ к всему объему этих данных и если бы они что-то замышляли, то они и так это сделали бы (ну, разве что теперь можно тыкать пальцем во всяких непорядочных чуваков, которые слили базы, что они виноваты))))
Как интересный пример могу привести информацию об американском SSN.


Your Social Security number is a high-value target for ID theft. Getting an identity theft protection plan is one step to consider.
Your Social Security number, or SSN, is a key piece of personally identifiable information.

https://us.norton.com/internetsecurity-id-theft-10-tips-to-help-protect-your-social-security-number.html#:~:text=Your%20Social%20Security%20number%20is%20a%20high%2Dvalue%20target%20for,piece%20of%20personally%20identifiable%20information.


И речь про просто номер… Я уверен, что его ценность примерно на уровне # паспорта или ИНН. И не просто так рекомендуют его защищать, не так ли? А тут, извините, целая база… ну, е-мае
Ну, и нужно определиться — играем ли мы в открытость, или все-таки скрываем все что можно от нежелательных глаз :-) на двух стульях не получится усидеть

Вместо sqlite берем PostgreSQL.

Далее:

CREATE EXTENSION pgcrypto;

INSERT INTO users (email, password) VALUES (
  'johndoe@mail.com',
  crypt('johnspassword', gen_salt('bf'))
);

SELECT id 
  FROM users
 WHERE email = 'johndoe@mail.com' 
   AND password = crypt('johnspassword', password);


Все, конец истории.
Выбирать, реализовывать свои криптоалгоритмы НЕ НУЖНО.
И чем же это поможет от перебора номеров паспортов? Никакого email в таблице не должно быть, только шифрованный/хэшированный номер паспорта и значение, проголосовали по этому номеру или нет.
омг… я ничего да что я под крипт подставляю одно поле? взял пример из мануала
Вон выше пример хеширования в полстроки кода, добавляйте is_voted boolean not null default false и вперед.
А чем принципиально ваш вариант отличается от того, что в статье?
Что мешает запустить перебор номеров с запросом?
SELECT *
  FROM passport
  WHERE num = crypt('1234567890', num);
Мешает то, что алгоритмы очень медленные. На core i5 там порядка 3000 хешей в секунду.
Кроме того размышлять о солении уже не нужно совершенно. (а тут половина комментариев на тему солений)
_
(а тут половина комментариев на тему солений)

хорошо, что соления, а не маринования )))

Тогда утыкаемся в другую проблему.
Учитывая, что в базе было более миллиона паспортов, проверка одного паспорта заняла бы до 6 минут, в среднем — 3 минуты.
Получается порядка 20 человек в час, 240 человек за всё время работы участка. Значит на один участок вам надо дополнительно посадить 13-15 проверяющих с компьютерами.
Алгоритм медленный а не поиск по базе, поиск по миллиону уложиться в 10 мс по btree.
Как он уложится, если поиск идёт только по зашифрованному полю?
Вместо sqlite берем PostgreSQL.

Ну это как «вместо батарейки АА берём РИТЭГ».

Ваша версия degvoter будет при запуске устанавливать локальный PostgreSQL-сервер и разворачивать в нём базу? А при закрытии приложения всё это сносить?
моя версия будет закрыта потому что я за такое не возьмусь вообще никогда. Но тут простыня комментов о том как солить правильно, в нарушение первого правила криптографии «не изобретайте свою криптографию»

ЗЫ напомните кстати, что плохого в том чтобы поставить-запустить локально PG?
В постановке задачи, под которую написан рассматриваемый код, на входе алгоритма только один параметр — номе паспорта.
В стандартном же алгоритме сохранения (хеширования) пароля (который использовали вы) на входе два параметра — имя пользователя (email) и пароль (номер паспорта).
И это главное отличие.
Вам для паспортов email нужен? нет, вот и уберите его)
Грамотная реализация шифрования или хэширования должна быть non-deterministic, то выглядеть как псевдослучайная информация. Соль должна быть уникальной для каждой записи в такой БД. Хэшированные данные станут подобны белому шуму.
Однако такая реализация не позволит построить поисковый индекс, чтобы находить записи по исходным данным, потому что результат хэширования без знания соли случаен.

Неизбежно придется идти на компромиссы, реализуя все-таки deterministic хэширование. Однако и его можно реализовать так, что вычислительные затраты на подбор хэша окажутся неприемлемыми.

Я бы предложил реализовать задачу хэширования следующим образом:
1. Нормализовать номер паспорта в строку, как исходные данные
2. Создать скажем 10 (100, etc) статических солей размерностью в 128 бит, сохранить их БД в соседней таблице
3. Рассчитать хэш-функцию blake2b от исходных данных, взять остаток от деления на 10 (100, etc), это будет порядковый номер соли
4. Рассчитать хэш-функцию Argon2 с параметрами: выбранная соль, исходные данные, размер получаемого digest 256 bit, parallelism=1, memory=16..32 MiB, iterations=5..7.

Хэш-функции семейства Argon2 спроектированы для противодействия атакам перебора на фермах GPU, они обеспечивают не только вычислительную нагрузку, но и расход памяти, также невозможность распарралелливания вычислений. Перебор хэшей Argon2 займет неприемлемое время. Вычисление одного хэша для поиска по БД займет почти незаметное для пользователя время.

Ни разу не криптограф, но выскажусь, какое решение видится с отдаленного ракурса.
Сделать вышепредложенное многократное хеширование hash(hash(hash(...(hash(data))), только не одним алгоритмом, когда злоумышленнику нужно тупо долбить, пока не получит читабельные данные, а несколькими.
Допустим, берем два алгоритма с одинаковым размером и набором выходных данных (aes-256 и sha256, к примеру). Суммируем все цифры серии и номера паспорта, получаем число от 0 до 90. Это число в виде битовой маски применяем к функции хеширования так, чтобы значимый бит означал SHA, а нулевой AES. Получаем сложность 90 x 29 x 10^6 (из комментария #comment_21835126), умноженную на 2^7. Для усложнения можно повторить хеширование по тому же алгоритму или добавить несколько правил вида "если вторая цифра номера паспорта четная, то добавляем sha1024(md5sum(data)) в начале четвертой итерации, иначе в конце" или "последняя цифра серии означает, на какой из итераций сдвинуть побитово данные на предпоследнюю цифру номера".
Если нужно скрыть факт голосования, то перед последнем хешировании для проголосовавших инвертировать последний/первый бит. Получим два хэша, которые и будут искаться в базе простым поиском — если найден только один, то даём человеку проголосовать и добавляем второй.
Да, смахивает на security through obscurity и если злоумышленник сможет определять, какой вид шифрования был выбран, то сложность взлома упадёт, но от "медузы" и рядовых хакеров спасёт, а люди с доступом к серьезным мощностям просто купят эту базу у МВД (или ботнетом вытащат её с сайта проверки валидных паспортов).

Прочитал аж три раза, чтобы понять проблему, описываемую автором, не нашёл; наверное дурак:


  1. Представлен кусок кода, названный говнокодом. По мне, чистенький, понятный код. Откомментить, и можно хоть в учебник вставлять.
  2. Плохая архитектура? Разработчику дали базу с хэшами номеров паспортов и сказали написать драйвер для использования на локальной машине члена центральной избирательной комиссии. Он это и сделал.
  3. БД на сервере? Зачем, если ее будут использовать от силы 5 человек в ЦИК, которые проводят выборочную проверку голосовавших дистанционно.
  4. Привело к утрате личных данных? Архитектура и код здесь вовсе ни при чем. Утечка произошла из-за того, что какой-то кретин выложил архив в открытый доступ.