Pull to refresh
4
0

Пользователь

Send message

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

К слову, удалённый рабочий стол сам по себе как решен?

Существуют в виде зоопарка технологий. На выбор RDP, VNC, ssh -X. Есть линуксовые клиенты TeamViewer и AnyDesk. Оно всё в целом работает, но иногда не работает.

Начну издалека: какие там есть решения для организации видеоконференций так, чтобы окно можно было транслировать во встречу, при этом ссылки в этом окне были кликабельные для всех участников, как это сделано в PowerPoint/Teams?

Мне такие решения неизвестны. Но требовать такую функциональность от открытого софта просто нечестно (и несколько мелочно). Какой открытый стандарт описывает взаимодействие между софтом для видеоконференций и софтом для показа презентаций? Я такого стандарта не знаю. Одна конкретная компания сделала такую интеграцию между своими программами, и что теперь? Что именно должны предпринять, скажем, LibreOffice и Okular, чтобы ссылки в документах открывались на видеосозвонах в Teams? Какой-то другой софт, кроме PowerPoint, вообще умеет так делать?

Чем можно организовать прозрачный проброс аппаратного средства аутентификации в удаленный рабочий стол

Во FreeRDP заявлена поддержка проброса USB и смарт-карт. Но оно может и не заработать: там то версия протокола на сервере не та, то в udev правила не прописаны, то ещё что-то. Но в целом, клиент такое умеет. Но опенсорсного RDP-сервера с поддержкой проброса USB, скорее всего, не существует.

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

Мне совсем не понятно, что вообще может удостоверять видеопоток с удалённой видеокамеры. Это точно нужная фича?

Требуется решение, работающее глобально

В вашем случае оно «работает глобально» только по той причине, что и ОС, и RDP-клиент, и RDP-сервер, и служба сертификатов, и вообще весь софт в цепочке, вплоть до серверов Azure, подконтрольны одной компание. Причём эта компания активно старается сделать удобно тем, кто внутри пузыря, и неудобно тем, кто снаружи.

Как по мне, пусть лучше оно работает менее глобально.

В продолжение моего комментария к первой части статьи.

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

Давайте посмотрим на ваш алгоритм:

c_i = H(\mathrm{PBKDF2}(k, s) \mathbin\Vert i) \oplus m_i.

Из тех же соображений, что приведены в моём первом комментарии, мы можем заменить его на эквивалентный по стойкости шифр

c_i = \mathrm{PRF}(\mathrm{PBKDF2} (k, s) \mathbin\Vert i) \oplus m_i,

где PRF — некая стойкая псевдослучайная функция. Однако, PBKDF2 — это тоже ни что иное, как стойкая псевдослучайная функция с настраиваемой степенью сложности. То есть, мы можем записать и так:

c_i = \mathrm{PRF}(\mathrm{PRF2}(k, s), i) \oplus m_i.

Композиция по ключу двух стойких псевдослучайных функций сама является стойкой псевдослучайной функцией, и мы можем дальше рассматривать одну функцию:

c_i = \mathrm{PRF}' (k, (s, i)) \oplus m_i.

Это выражение, в общем-то, ни что иное, как обобщённая схема блочного шифра в режиме работы со счётчиком и nonce. Она стойкая, если:

  • ключ k выбирается случайным образом,

  • для шифрования каждого нового сообщения используется уникальное значение величины s.

Вообще говоря, тут от соли не требуется быть случайной, требуется только уникальность пары (k, s). Поэтому соль тут не вектор инициализации, как написано у вас, а именно nonce. Можно использовать простой счетчик сообщений, и это не повлияет на стойкость.

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

Рекомендую прекратить изобретать велосипеды и пройти уже, наконец, на курсере стенфордский онлайн-курс по криптографии. Он очень классный, странно, что ещё никто не порекомендовал.

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

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

Вот ваш шифр:

c_i = H (k \mathbin\Vert i) \oplus m_i.

Давайте дополнительно потребуем, что:

  • ключ k должен быть фиксированной битовой ширины (то есть, никаких «main key» произвольной длины!),

  • счётчик i тоже должен быть фиксированной битовой ширины (достаточной для хранения индекса блока даже безумно длинного сообщения).

Эти дополнительные требования исключают length-extension-атаку на хеш-функцию, поэтому, интуитивно, её стойкость в этом сценарии будет эквивалентна стойкости конструкции HMAC от неё. Поэтому мы можем переписать ваш шифр на эквивалентный по стойкости:

c_i = \mathrm{HMAC}_H(key, i) \oplus m_i.

Далее предположим, что функция H построена по схеме Меркла-Дамгора (SHA-256 именно такая) и лежащая в её основе функция компрессии является криптоскойкой псевдослучайной функцией (для функций семейства SHA на данный момент не доказано обратного). Для таких хеш-функций доказано†, что \mathrm{HMAC}_H является стойкой псевдослучайной функцией (PRF) относительно ключа. Следовательно, снова можем переписать шифр на эквивалентный по стойкости:

c_i = \mathrm{PRF}(k, i) \oplus m_i.

Это выражение — классический блочный шифр в режиме со счётчиком. Его стойкость доказана при условии, что:

  • ключ k выбирается случайным образом из множества возможных ключей,

  • ключ используется для шифрования не более чем одного сообщения.

Этот вывод, вообще говоря, довольно очевиден с самого начала, если вспомнить, что SHA-256 построена на основе полноценного блочного шифра SHACAL-2. С тем же успехом можно было бы просто применить этот блочный шифр напрямую.

† В доказательство этого утверждения я никогда подробно не вчитывался, поэтому сошлюсь тут Википедию, https://en.wikipedia.org/wiki/HMAC:

In particular, Mihir Bellare proved that HMAC is a pseudo-random function (PRF) under the sole assumption that the compression function is a PRF. [далее ссылка на PDF с публикацией]

Всё остальное - субъективно.

О какой вы субъективности?

Где ответ NULL зарезервирован и является индикатором ошибки.

Это неправда. Стандарт прямо говорит, что у memset и memcpy никакое значение не зарезервировано для индикации ошибки. То есть, ни NULL, ни какое-то ещё. Ваши функции тестируют невозможные ситуации.

Там по вашей второй ссылке написано:

The memcpy() function shall return s1; no return value is reserved to indicate an error.

И то же самое сказано на странице про memset. Для меня это выглядит так, как будто проверять, не вернули ли эти функции NULL, нет никакого смысла.

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

Судя по тому, что на баннере написано «source code available» и далее по ссылкам лишь обтекаемые формулировки и нет подробностей о лицензии, исходный код они не открывают, а показывают. Видимо, «модель совместного развития» — это когда сообщество помогает делать проприетарный продукт.

Вот еще пара функций, которая мне также неоднократно пригождалась

А для чего именно вам были полезны такие memset и memcpy? Я вижу, что при некоторых значениях аргумента n они просто возвращают NULL вместо того, чтобы делать свою работу, но ума не приложу, зачем такое поведение может понадобиться в тестах.

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

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

А как атакующему воспользоваться этой уязвимостью? Промежуток времени такой есть, но всё это время каталог пуст.

Гугл отменит возможность чтения писем в браузере

А можно подробнее? А то я что-то нагуглить не могу.

Несколько лет назад, когда преподавал в университете, покупал для лаб за свои деньги полдюжины плат Lattice MachXO3L StarterKit — стоили они тогда примерно 30 баксов за штуку. Сами платы довольно приятные, но слегка спартанские: есть программатор, тактовый генератор, несколько светодиодов и DIP-свитчей и тонна GPIO — если для лабы нужно что-то ещё (например, семисегментный индикатор или угловой энкодер, до звука и видео просто не успевали дойти за семестр), студенты собирали это что-то рядом на макетках. Это занимало кучу времени, но студенты готовы заниматься чем угодно, лишь бы код не писать.

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

И правильно делают, в противном случае преподаватель только тем и будет заниматься, что бегать от студента к студенту, разбираясь с их «А почему у меня не работает?!». Я бы ещё и периферию всю использовал максимально одинаковую, чтобы не получить комбинаторный взрыв у себя в голове.

В следующей статье подумаю над чем-нибудь менее бросающимся в глаза

Как насчёт такого?

// Файл: client/model.c
// Функция: void Mod_LoadTexinfo (lump_t *l)

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

Скажите, пожалуйста, вам не кажется, что полсотни комментариев // PVS-Studio: в одной статье — это как-то слегка перебор? Это у вас KPI для технических писателей такое?

... но она не имеет ассоциаций для вашей памяти

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

... и это в той же степени криптостойкий пароль.

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

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

... но он состоит из реальных слов, которые попадают под dictionary attack.

Если ваш пароль состоит из достаточного количества случайных словарных слов, уже неважно, что каждое по-отдельности — словарное.

... это больше на тему юмора и концепции, чем про реальное применение.

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

Думаю, вы зря так быстро отбросили DVI: он простой, как палка и верёвка, и работает на любой разумной пискельной частоте.

Выяснилось, что [HDMI —] последовательный, а это значит, частота вывода пикселей составляет порядка 25 МГц, а после сериалайзера — все 250 МГц.

Это совершенно не проблема. Если верить даташиту на это семейство ПЛИС, OSERDES2 (сериализующий выходной дифференциальный буфер) на чипах спидгрейда -2 (такой чип на картинке) выдаёт 500-1080 мегабит/с в зависимости от источника клока. Если не все OSERDES2 заняты под DDR-память, на них можно было бы организовать видеовыход.

Цифры я смотрел тут: https://docs.xilinx.com/v/u/en-US/ds162, стр. 18.

К тому же этот интерфейс требует модуль TMDS [...]

У этого семейства заявлена поддержка TMDS, но есть ограничения по банкам и питающим напряжениям. Для TMDS-источника даже внешних резисторов не надо, они ставятся на стороне приёмника.

Про схему согласования есть в другом даташите: https://docs.xilinx.com/v/u/en-US/ug381, стр. 36.

Внутри данного интерфейса, как и у HDMI, есть LVDS-линии [...]

У вас тут фактическая ошибка. LVDS — это не общий термин для вообще любого дифференциального интерфейса, а отдельный стандарт. У LVDS и TMDS отличаются уровни напряжений и по-разному делается согласование приёмника с источником. Поэтому ни в DVI, ни в HDMI нет LVDS-линий.

А что выберешь ты?

Для честного голосования добавьте вариант: «Ничего не предпринимать». Появится ваш василиск — будем решать проблему.

И именно в этом видится настоящая угроза человечеству.

У человечества есть тысяча угроз пострашнее этой унылой псевдофилософской концепции. Вся значимость которой, к тому же, раздута из единственного поста Юдковского и прикольного названия.

Модуль AES сейчас стоит даже в копеечных старших STM32

Так AES — симметричный блочный шифр. На его основе легко сделать «банальный MAC», но ускорить асимметричные шифры такой аппаратный модуль ни капли не поможет.

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

Вот только в приведённых примерах нет никакого нарушения вложенности.

Я бы сделал здесь две разные реализации функции: [...]. Суть длиннее, но читать код намного приятнее.

Имхо, вкусовщина. Лично мне читать стало менее приятно, потому что стало сложнее понять, чем же именно эти функции различаются — нужно сравнить не только смысловые строчки, но и сигнатуры функций, чтобы убедиться, что эти сигнатуры идентичны в обоих вариантах (точно ли они обе const noexcept, например). Чем меньше строк под #ifdef, тем лучше.

Мне кажется, что я перепробовал все варианты, но решения так и не нашел.

А пробовали, как выше предлагает @fk0, объявить ссылку на функцию? Как-то так:

#include <cstdio>

int foo(float x) {
    return 0;
}

constexpr const auto& bar = foo;

int main() {
    foo(1.0f);
    bar(1.0f);
    std::printf("%p\n", foo);
    std::printf("%p\n", bar);
    std::printf("%p\n", &foo);
    std::printf("%p\n", bar);
}

и за одну ночь к нему прилипает примерно 300-500тыс рублей процентами

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

1
23 ...

Information

Rating
5,449-th
Location
Воронеж, Воронежская обл., Россия
Registered
Activity