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

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

у нас 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 это кодирование, не шифрование

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

Согласуется посредством дышла, очевидно.

А я написал три слова и три группы цифр, придуманные только что из головы: Пафнутий Аристархович Шпротов, 20.02.2002. Я тоже разгласил чьи-то данные?

Этот вопрос интересует не только меня, но и весь наш отдел народного образования Отдела Народного Образования ©.
По идее это будет персональными данными, если с этими цифрами ещё как минимум фамилию приписать.
Номера паспортов неуникальные.
Номера паспортов неуникальные.
#даладно!
Из-за твоего коммента мне пришлось пойти перепроверить.
Сочетание серия-номер уникальное, номер — неуникальный.
Согласен. Просто отдельно номер паспорта практически нигде не используется. Везде связка серия+номер. Поэтому часто говорят «номер», подразумевают полный номер, который вместе с серией.
Неуникальность номера можно было и не проверять. 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 В качестве решения навскидку видится только внесение изменений в законы о выборах или в сам закон о персональных данных, где явно прописать, что информация о способе голосования может быть открытой.
Ну и как обычно, 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+ТБ/с ради того чтобы не дать проверить номер паспорта.