Pull to refresh

Comments 143

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

Подобраться физически как можно ближе к атакуемому серверу, запускать подбор, когда большинство пользователей спят, повторять запросы тысячи раз, чтобы отфильтровать все случайные девиации за счёт усреднения — всё это вполне может обеспечить атаке успех.
Я не располагаю достаточными знаниями и ресурсами (в силу того, что я мобильный девелопер), но если бы напишете статью с проверкой подобной схемы — уверен, она выйдет в топ первой страницы хабра.
Не попадет.
А перепечатывать учебники по статистике на хабр… ну фиг знает.
Существует такая штука — квант времени процессора. Также между ядром и NIC лежит driver queue с непредсказуемым latency. Я уж не говорю про очереди на всех промежуточных рутерах. Все эти элементы вносят непредсказуемые задержки, которые намного больше искомой величины. Уровень шума на несколько порядков превышает сигнал, как тут что-то можно отфильтровать с негативным SNR — я лично не знаю (но я не эксперт в DSP или статистике). Было бы интересно узнать, если такие способы есть.
UFO just landed and posted this here
Ключевое слово здесь — «типа того». В GPS используется не шум, а псевдослучайный (строго закономерный) сигнал.
Нет-нет, псевдослучайный сигнал как раз испольузется для того, чтобы бороться с шумами. Шумы там действительно сильнее полезного сигнала, но не показывают требуемой псевдослучайной закономерности, за счёт чего и отсекаются.
Прощу прощения, разве количество попыток аутентификации не ограничено?
Ограничивают попытки обычно с определённого адреса или по каким-то дополнительным признакам, иначе легкая атака может привести к перманентной блокировке целевого аккаунта и легальный пользователь даже зная пароль не сможет войти.
Вот-вот!

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

Поэтому защита выставленного наружу RDP-сервера делается всякими костылями. Например, анализом логов подсистемы безопасности. Но в них не всегда IP фиксируется.
Про скорости сравнения строк — 44:53 «All these appeared to be exploitable over the LAN, but not Internet — we're dealing with 43 to 44 nanoseconds average». Это в Java, которая оказалась в 40 раз медленне других — C, питон, руби. А если сервер на ruby?
Вобщем непонятно, реально ли вообще такой эксплойт провести (особенно если исходники того, что на сервере, не доступны атакующему, и он не знает что там и как сравнивается и при каких условиях).
Вспоминается XKCD: xkcd.ru/538/
Вы неправы. В pdf говорится, что атакующая и атакуемая машины находились в разных зданиях, и между ними были три роутера и несколько свитчей.

Ссылка, которую я привёл выше, к сожалению, не работает. Вот правильная — Remote timing attacks are practical
А где там про роутер и несколько свичей? В статье, на которую вы ссылаетесь, речь идёт про всего один свитч. Хотя это тоже интересно, конечно.

To show that local network timing attacks are practical, we connected two computers via a 10/100 Mb Hawking switch, and compared the results of the attack inter-process vs. inter-network.
Figure 6 shows that the network does not seriously diminish the effectiveness of the attack.
The noise from the network is eliminated by repeated sampling, giving a similar zero-one gap to
inter-process. We note that in our tests a zero-one gap of approximately 1 millisecond is sufficient to
receive a strong indicator, enabling a successful attack. Thus, networks with less than 1ms of variance are vulnerable.
«сетевое расстояние в эксперименте было маленьким» — конечно, это означает что был маленький пинг
UFO just landed and posted this here
Балансировщик случайно одного и того же клиента намеренно не перенаправляет на одну и ту же ноду? А то иначе встаёт проблема синхронизации локального состояния нод…
На coursera есть совершенно потрясающий курс основ криптографии стэнфордского университета, там и не такие вещи рассказывали. Если тема интересна — не проходите мимо.
Очень хороший курс, в тему топика, автор почти в каждой лекции говорил не изобретать алгоритм шифрования самому, а использовать проверенные надежные.
Обещал себе не брать курсы на лето, ибо нефиг дома сидеть за компом. Но prof. Dan Boneh так складно говорил…
Да. Но, только MD5 — плохой пример, вот md5(unix) думаю подойдёт.
Согласен с вами, звучит не серьезно. Хоть посыл в статье и правильный, но примеры доставляют…
Накидал код в сях, связь с серваком по сокетам (асинк), локалка 1Gb.
Перебор «HMAC» от AAAAAA до ZZZZZZ, при правильном ZZZZZZ.
Разброс в ответе на реквест дельта от 70нс до 220нс, при 1-10% нагруженой сетке.
Разброс локально (localhost->localhost) дельта от 50нс до 85нс. Причем совершенно не важно сколько букв правильно. Даже тенденции нет.
И это при том, что сервак ничего кроме перебора не делал (multithreaded).
Переложил на CPU cycle counter через rdtsc, чтобы исключить колебания по времени (неточность таймера). Разбег от 5 до 18, кому интересно под спойлером парочка значений — для правильного последнее. Все localhost…
Тест single thread
cycle---dif
957323843---6
957323856---5
957323875---5
957323886---5
957323896---5
957323907---5
957323917---5
957323928---5
957323938---6
957323949---5
957323960---5
957323970---5
957323981---5
957323991---6
957324002---5
957324012---5
957324023---5
957324033---6
957324044---5
957324055---5
957324065---5
957324075---5
957324086---15
957324106---6
957324117---5
957324128---5
957324139---5
957324150---5
957324161---5
957324172---5
957324183---5
957324193---6
957324205---5
957324215---6
957324226---5
957324237---5
957324248---5
957324259---5
957324269---6
957324280---6
957324291---5
957324302---5
957324312---6
957324323---5
957324334---5
957324344---6
957324355---5
957324366---6
957324377---5
957324388---5
957324399---5
957324410---5
957324420---6
957324431---5
957324442---5
957324453---5
957324464---5
957324475---5
957324486---5
957324496---6
957324507---5
957324517---5
957324528---5
957324539---5
957324550---5
957324560---6
957324571---5
957324582---13
957324600---5
957324610---6
957324621---5
957324631---5
957324642---5
957324652---5
957324662---6
957324673---5
957324683---5
957324693---6
957324704---5
957324714---5
957324725---5
957324735---6
957324746---5
957324756---5
957324767---5
957324777---5
957324787---5
957324798---5
957324808---5
957324819---5
957324839---5
957324849---6
957324860---5
957324871---5
957324881---6
957324892---5
957324903---5
957324913---6
957324924---5

Тест 5 threads
cycle---dif
1368424031---10
1368424048---9
1368424065---8
1368424080---8
1368424096---8
1368424111---8
1368424126---9
1368424142---8
1368424158---7
1368424173---8
1368424188---8
1368424204---8
1368424219---8
1368424234---8
1368424250---7
1368424265---8
1368424280---8
1368424295---9
1368424311---8
1368424327---7
1368424342---8
1368424357---7
1368424372---8
1368424387---8
1368424402---9
1368424418---8
1368424433---8
1368424448---8
1368424464---8
1368424479---8
1368424494---8
1368424510---7
1368424525---8
1368424540---8
1368424555---8
1368424570---8
1368424585---8
1368424600---8
1368424616---7
1368424631---7
1368424646---8
1368424661---8
1368424676---8
1368424692---8
1368424707---8
1368424722---8
1368424737---8
1368424752---8
1368424768---8
1368424783---8
1368424798---8
1368424813---8
1368424828---8
1368424844---8
1368424859---8
1368424874---8
1368424890---7
1368424905---7
1368424920---8
1368424935---8
1368424950---8
1368424965---8
1368424981---7
1368424996---8
1368425011---8
1368425026---8
1368425041---8
1368425056---8
1368425072---7
1368425087---8
1368425102---8
1368425117---8
1368425132---8
1368425147---8
1368425163---7
1368425177---8
1368425192---8
1368425208---8
1368425223---8
1368425238---8
1368425253---8
1368425269---8
1368425284---8
1368425299---8
1368425314---8
1368425329---8
1368425344---8
1368425360---8
1368425375---8
1368425390---8
1368425405---8
1368425421---8
1368425436---8
1368425451---8
1368425466---8
1368425481---8
1368425497---7
1368425512---8
1368425527---8
Упростил перебор:
Cравненивал через strcmp, stricmp и даже string::operator ==
В выдаче:
1ST_NOT_EQ — сравнивает AAA...AAA (64-е раза А) c ZZZ...ZZZ (64-е раза Z), хотя после первой неправильной буквы return -1
ALL_EQUAL — сравнивает ZZZ...ZZZ c ZZZ...ZZZ, соответственно return 0
Результаты теста
1ST_NOT_EQ---3973032722---8
ALL_EQUAL----3973032736---8
1ST_NOT_EQ---3973032750---7
ALL_EQUAL----3973032764---7
1ST_NOT_EQ---3973032777---8
ALL_EQUAL----3973032791---7
1ST_NOT_EQ---3973032804---7
ALL_EQUAL----3973032817---7
1ST_NOT_EQ---3973032831---7
ALL_EQUAL----3973032844---7
1ST_NOT_EQ---3973032858---7
ALL_EQUAL----3973032871---7
1ST_NOT_EQ---3973032884---7
ALL_EQUAL----3973032897---7
1ST_NOT_EQ---3973032911---6
ALL_EQUAL----3973032923---7
1ST_NOT_EQ---3973032937---7
ALL_EQUAL----3973032950---7
1ST_NOT_EQ---3973032963---7
ALL_EQUAL----3973032977---7
1ST_NOT_EQ---3973032990---7
ALL_EQUAL----3973033003---6
1ST_NOT_EQ---3973033016---7
ALL_EQUAL----3973033028---7
1ST_NOT_EQ---3973033042---6
ALL_EQUAL----3973033055---6
1ST_NOT_EQ---3973033068---7
ALL_EQUAL----3973033082---7
1ST_NOT_EQ---3973033095---7
ALL_EQUAL----3973033110---7
1ST_NOT_EQ---3973033123---7
ALL_EQUAL----3973033137---7
1ST_NOT_EQ---3973033151---8
ALL_EQUAL----3973033165---7
1ST_NOT_EQ---3973033178---7
ALL_EQUAL----3973033191---7
1ST_NOT_EQ---3973033205---7
ALL_EQUAL----3973033218---7
1ST_NOT_EQ---3973033231---7
ALL_EQUAL----3973033244---6
1ST_NOT_EQ---3973033257---6
ALL_EQUAL----3973033269---7
1ST_NOT_EQ---3973033282---7
ALL_EQUAL----3973033296---7
1ST_NOT_EQ---3973033309---7
ALL_EQUAL----3973033322---7
1ST_NOT_EQ---3973033336---6
ALL_EQUAL----3973033348---7
1ST_NOT_EQ---3973033362---7
ALL_EQUAL----3973033375---8
1ST_NOT_EQ---3973033389---28
ALL_EQUAL----3973033427---10
1ST_NOT_EQ---3973033445---8
ALL_EQUAL----3973033459---8
1ST_NOT_EQ---3973033473---8
ALL_EQUAL----3973033487---7
1ST_NOT_EQ---3973033501---7
ALL_EQUAL----3973033516---7
1ST_NOT_EQ---3973033530---7
ALL_EQUAL----3973033543---7
1ST_NOT_EQ---3973033556---7
ALL_EQUAL----3973033569---7
1ST_NOT_EQ---3973033582---7
ALL_EQUAL----3973033595---7
1ST_NOT_EQ---3973033608---7
ALL_EQUAL----3973033621---8
1ST_NOT_EQ---3973033635---7
ALL_EQUAL----3973033648---7
1ST_NOT_EQ---3973033661---7
ALL_EQUAL----3973033674---7
1ST_NOT_EQ---3973033687---7
ALL_EQUAL----3973033700---7
1ST_NOT_EQ---3973033714---6
ALL_EQUAL----3973033727---7
1ST_NOT_EQ---3973033740---7
ALL_EQUAL----3973033753---6
1ST_NOT_EQ---3973033766---7
ALL_EQUAL----3973033779---6
1ST_NOT_EQ---3973033792---7
ALL_EQUAL----3973033804---7
1ST_NOT_EQ---3973033818---7
ALL_EQUAL----3973033831---7
1ST_NOT_EQ---3973033844---7
ALL_EQUAL----3973033857---7
1ST_NOT_EQ---3973033870---7
ALL_EQUAL----3973033883---7
1ST_NOT_EQ---3973033896---7
ALL_EQUAL----3973033910---7
1ST_NOT_EQ---3973033923---6
ALL_EQUAL----3973033936---7
1ST_NOT_EQ---3973033949---7
ALL_EQUAL----3973033962---7
1ST_NOT_EQ---3973033975---7
ALL_EQUAL----3973033988---7
1ST_NOT_EQ---3973034001---7
ALL_EQUAL----3973034014---7
1ST_NOT_EQ---3973034027---7
ALL_EQUAL----3973034040---7

Может кто все-таки подскажет каким-таким способом я могу словить разницу во временной задержке? Может использовать реал-тайм систему, другой таймер, еще что-либо?
Кроме того объясните мне, как подобрать 64 байта, если я даже для первого не вижу задержки.
Да никаким, очевидно же, что автор просто пугает и навязывает идею о том, что вы «не компетентны в криптографии».

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

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

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

А плодить лишние XOR'ы чтоб «никто не отследил» это какое-то извращение.
Все так, просто чтобы озвучить «риторичность» вопроса — полностью асинхронный пул на ринг буферах который делал только «перебор», без контекст-свич (8 цпу), блокировок и ко. Время замера от коннекта и реквеста, т.е. только ответ. Без сети — ибо localhost. Т.е. не «шумим».
Как-то так.
Судя по фамилии, писал индус, а они любят громкие слова и интриги с расследованиями.
Судить о человеке по фамилии или национальности — это очень глубоко, да…
Если вы знаете значение md5('foo'), в силу способа вычисления MD5 можно очень легко посчитать значение md5('foobar'), даже не зная префикса 'foo'.

Только не foo, а блок из 512*k бит, ну или «foo»+padding. И будет, соответственно, не «foobar», а «foo»+padding+«bar»
Вы, безусловно, правы. А автор (не думаю, что он об этом не знал), видимо, решил спрятать это за своим «Вкратце».
Деталь, в общем-то, существенная. И в некоторых случаях вполне может сделать атаку невозможной.
А можете продемонстрировать? Я никак не могу понять этот тип атак.
Я видел его. И по ссылкам там ходил. Там примеры куцые какие-то везде. Я хочу воспроизвести эту атаку. Вы можете мне помочь?

Например, пусть у нас есть урл:

site.com/?param=protected&sig=9bf4a1a22db9b764a36af4746864b847

Здесь sig = md5(key+protected). Я хочу получить:

site.com/?param=hacked

Как мне это сделать?
Именно так — не получится.
Суть Length extension в том, что к сообщению добавляются новые байты. Заменить исходные не выйдет.
Т.е. в лучшем случае, у вас получится что-то вроде
site.com/?param=protected\x80\x00\x00...\x00\xNN&param=hacked
а мне кажется сам пример некорректным. Нелья непосредственно подписываемый запрос добавлять подпись этого запроса. Можно поместить запрос в контейнер, который подписать и уже вместе с контейнером посылать подпись
А что такое этот «контейнер» в контексте, например, HTTP запроса?

Предлагаете придумать какой-то свой формат передачи параметров и заново реализовывать формирование запроса на клиенте и парсинг на сервере? А также обработку специальных случаев (мульти-значения, искейпинг) и пр. Т.е., по сути, отказаться от всех удобств работы с параметрами, предоставляемых используемым фреймворком (никаких больше params[:user_id] «из коробки»).
Суть Length extension в том, что к сообщению добавляются новые байты. Заменить исходные не выйдет.

Это я понял.

Т.е. в лучшем случае, у вас получится что-то вроде
site.com/?param=protected\x80\x00\x00...\x00\xNN&param=hacked

Именно. Как мне этого добиться?
Пришлось сдуть пыль с компилятора для C (на удивление, ни в одном более высокоуровневом языке нельзя подсунуть в MD5 начальный контекст).

Я немного изменил формат передачи сообщения серверу, чтобы пример был более наглядным.

    MD5_CTX seed;

// оригинальный запрос к серверу:
// example.com/?msg=status:protected&sig=039f220db17cebe441bc4d34e6683963

    MD5_Init(&seed);
    // секрет + тело сообщения
    char *msg = "900150983cd24fb0d6963d7d28e17f72" \
        "status:protected";
    printf("%s\n", md5(msg, strlen(msg), &seed));
    // = 039f220db17cebe441bc4d34e6683963 - это и есть подпись для исходного сообщения

    MD5_Init(&seed);
    // та самая исходная подпись, порезанная на части
    seed.A = 0x0d229f03;
    seed.B = 0xe4eb7cb1;
    seed.C = 0x344dbc41;
    seed.D = 0x633968e6;
    // длина исходного сообщения с секретом в битах, округлённая вверх до кратного 512 значения
    seed.Nl = 512;
    seed.Nh = 0;

    // вычисляем новый хэш (= подпись), исходя из начального значения и нашей "добавки"
    char *extension = ",status:hacked";
    printf("%s\n", md5(extension, strlen(extension), &seed));
    // = 164bc99c345fd21e1e810bf9a41222b

// подделанный запрос к серверу:
// example.com/?msg=status:protected%80%00%00%00%00%00%00%00%80%01%00%00%00%00%00%00,status:hacked&sig=164bc99c345fd21e1e810bf9a41222b

    // а вот так будет считать хэш сервер
    // я специально порезал строку на части, чтобы лучше была видна структура:
    // секрет, исходное сообщение, паддинг, длина исходного сообщения с секретом, "добавка"
    MD5_Init(&seed);
    char *msg2 = "900150983cd24fb0d6963d7d28e17f72" \
        "status:protected" \
        "\x80\x00\x00\x00\x00\x00\x00\x00" \
        "\x80\x01\x00\x00\x00\x00\x00\x00" \
        ",status:hacked";
    printf("%s\n", md5(msg2, 78, &seed));    // strlen() тут не сработает - потому 78
    // = 164bc99c345fd21e1e810bf9a41222b - наша подпись подошла!


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

P.S. У Вас новый хеш обрезан. Должен быть 164bc99c345fd21e1e810bf9a41222b9.
Наивный вопрос, если мы развернём строку перед подсчётом md5 то спасёмся от этой уязвимости?
Тогда можно будет приписать свои данные перед сообщением.
sig = md5(секретный_ключ+значение_параметра_param). Ключ и значение параметра соединяются простой конкатенацией без разделителя.
Есть другие интересные примеры в несовершенстве криптографических систем.
Например, шифрование DVD, WPA, padding attacks.
«Атака по времени», с ума сойти… Это уже не криптография, это уже социальная инженерия какая-то. Короче, я некомпетентен, но я в восторге.
Есть целый класс атак, называемых Side Channel Attack (атак по побочным каналам). Вряд ли это социальная инженерия, это атаки, которые опираются не только на математическую базу, но и на аппаратные (физические) специфики реализации и работы каждой конкретной железки.
Очень интересны атаки по энергопотреблению, если реализация «лобовая», то такой атакой из черного ящика очень хорошо ключики асимметричных алгоритмов вытаскиваются.
Была замечательная статья (ссылку потерял) когда взламывали зашифрованный VoIP канал. Суть в том, что в канале использовалась технология VAD (Voice Activity Detection) которая уменьшает трафик когда речь не передаётся. По колебаниям объёма трафика, которые совершенно одинаковы как в открытом, так и и в шифрованном сообщении, оказалось возможным распознавать какие звуки произносят (всё по полной программе — строится скрытая марковская модель и так далее). То есть, удалось узнать текст, который зачитывается по зашифрованному каналу, вообще без взлома криптосистемы.
Уж простите, но я на это скажу «бред».
VAD останавливает передачу пакетов при снижении уровня громкости до определенного уровня. Кстати, его уже почти никто не использует — даже с генерацией комфортного шума эта технология очень раздражает собеседников. Колебания трафика от VAD — «вкл-выкл».
Во время передачи пакетов размер у всех пакетов всегда один и тот же. Я допускаю, что есть исключения, но я о них никогда не слышал. Скажем, 10 байт на 10мс у весьма эффективного g.729.
Допустим, можно выделить конкретный RTP поток из шифрованного туннеля и с абсолютной точностью узнать размер каждого из пакетов. Допустим, используется кодек, у которого размер пакета меняется в зависимости от «насыщенности» звуковой среды. Вы получаете цепочку цифр вида 20-20-20-17-15-12-20 (байт). Если вы построите модель, позволяющую из этой информации получить содержимое разговора, для переноса которого задействуется несравнимо больше битов информации (160 бит против, скажем, 6 бит) — смело патентуйте, будете миллиардером.
Вы, видимо, вот эту работу имели в виду: software.imdea.org/%7Ebkoepf/papers/esorics10.pdf
Но там речь идёт всё же об идентификации говорящего (по характерному отпечатку пауз от VAD), а не о раскрытии текста.
Вот ещё одна аналогичная работа 2007 года с тестами на SIP и Skype — etd.ohiolink.edu/send-pdf.cgi/Lu%20Yuanchao.pdf?csu1260222271

Но интереснее всего, пожалуй, опубликованная в 2011 работа, в которой пишут о распознавании фраз в зашифрованном потоке.
Они использовали не следы от VAD, а информацию о фонетическом произношении слов. При этом ни образцов голоса, ни образцов произношения входящих во фразу слов алгоритму не требуется. А атака стала возможной из-за комбинации VBR сжатия и сохраняющего длину шифрования.
www.cs.unc.edu/%7Efabian/papers/tissec2010.pdf
Видимо в памяти перемешались две этих статьи :)

Спасибо.
Когда я на почте на флоте служил ямщиком
Короче, связистом я служил в ракетном полку.
У нас там закрытый канал связи все время был чем-то занят: либо действительно что-то полезное передавал, либо что-то бесполезное, но суть как раз и была в том, чтобы затруднить обнаружение сообщения в канале связи.
Как в общих чертах генерировали бесполезные сообщения?
Не буду врать — не знаю. Нам (солдатам/сержантам) так глубоко в систему заныривать не давали.
Когда я служил в советское время то пользовался аппаратурой ЗАС для криптования, говорят что янки ломали шифр за 15 минут в основном от того что радист в начале сеанса всегда произносил фразу перед началом: «Один-Два-Три Заря я Гроза „
Ну там смысл немного другой. Это не для затруднения дешифрации, а для того, чтобы нельзя было обнаружить внезапное повышение активности. Т.е. скажем, передавали по каналу одно сообщение в неделю, а потом вдруг пришло десяток за день. Противник соответственно усиливает разведку на этом направлении — что за нездоровая активность?
Против атаки по времени зачем делать xor, если можно сделать sleep на случайное число миллисекунд?
На целое случайное число миллисекунд, ага. В принципе можно, наверное, но это костыль уже.
В мультизадачной среде SLEEP никогда не даст целое число миллисекунд, обычно это означает ОТ заданного количества миллисекунд и выше, конец такой задержки зависит еще и от выполнения других задач.
Плохо то что на серверах с высокой нагрузкой таким способом не отделаешься — тормозить все начнет безбожно.
если повторить один и тот же запрос тыщу раз, то ваш рандом будет в среднем одинаковый
Если делать sleep на случайное число миллисекунд от 1000 до 2000, то на повторение запроса 1000 раз уйдет не менее 20 минут. А 1000 раз — это мало. И это только один запрос, нам надо больше, намного больше…
Можно повторять запрос в несколько (десяток, сотен, тысяч) потоков
Это сложно отловить на стороне сервера? И эта многопоточность никак не скажется на времени, которое требуется серверу для обработки запроса?
Что проверять на стороне сервера? Брутфорс через ботнет?
Отлавливать это на стороне сервера — это костыль. Попытка закрыть несовершенство криптосистемы какими-то дополнительными средствами, которые к собственно криптографии никакого отношения не имеют. Вы получите странный, трудно поддерживаемый код.

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

Это какие-то два разных заключения…
«Готовой нормальной системой» надо ещё уметь пользоваться.

Берём какой-нть Triple DES, неправильно выбираем константу режима шифрования (ECB вместо CBC) — и получаем шифровку, которую можно спокойно резать на части и собирать новое сообщение из нескольких исходных — www.codinghorror.com/blog/2009/05/why-isnt-my-encryption-encrypting.html
Против атаки по времени зачем делать xor, если можно сделать sleep на случайное число миллисекунд?

Вы опасно некомпетентны в криптографии)
А что если сервер будет сначала помещать ответ в очередь, а извлекать его, только если текущее время кратно, к примеру, 100мс?

А что если сервер под такой атакой по времени тупо просядет? Как атакующая сторона справится с этим?

А что если отвечать со все увеличивающимся на случайную величину временем, если предыдущий запрос оказался невалидным?

Я опасно некомпетентен в криптографии? (:
Я опасно некомпетентен в криптографии? (:

Да)

Хотя, думаю, за 4 года у вас появился новый опыт и вы уже сами осознаете, что не так)
Да еще вчера понял, что это сильно усложнит, но не сделает невозможным статистический анализ. Как реальное практическое решение, лежащее за пределами чистой криптографии — оно неплохое. Но если находиться только в рамках криптографии — то да, я сморозил ерунду.

P.S. Под sleep можно понимать не только задержку на целое количество миллисекунд, но и какую-нибудь реализацию выполнения «мусорных» команд, занимающих такты процессора.
XOR делать незачем. Ибо не поможет. Во всяком случае в той редакции, которую предлагает автор:
Для сравнения строк мы можем воспользоваться тем фактом, что XOR любого байта с самим собой даст 0. Всё, что нам надо сделать — применить операцию XOR к каждой паре соответствующих байтов из строк A и B, сложить получившиеся результаты и вернуть true, если сумма равна 0, и false в противном случае.

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

Если же разрядность арифметической суммы больше 8 бит, то уже может казаться надежным. Но это надо еще проверить, совпадает ли время сравнения двухбайтовых (четырехбайтовых) чисел, если у них старшие байты нулевые/не нулевые. Если есть хоть небольшая разница, то это уже можно попытаться использовать.

Интересно, а легко ли будет уловить разницу во времени, если сравнение начинается не с первого байта, а с рандомного и по циклу?
Можно подавать на вход хеш из одинаковых символов. Чем их больше в хранимом хеше, тем больше будет среднее время задержки до отлупа. Затем перейти к поиску пар и т.д. Алгоритм, будет сложным и длительным, но, возможно, все же эффективнее брута.
Современные процессоры оперируют числами разрядностью 32/64 бита, поэтому при сравнении чисел разрядностью меньше указанной они сначала расширяются а потом только идёт сравнение, причем расширение до указанной битности может происходить на уровне компиляции и разницы во времени выполнения не будет. И разницы для сравнения не с первого байта тоже не будет — всеравно при обращении к памяти будет прочитана порция размером в одну кеш-линию, а это достаточно много байт и разницы какой байт программа запросила первым в пределах 8-16 байт НЕ БУДЕТ. Этому ещё способствует выравнивание структур данных по границам страниц, наша переменая с хешем скорей всего будет расположена ровно в начале границы и попадёт полностью в одну кеш-линию а это значит время первого доступа к ЛЮБОЙ части хеша будет одинаковым и определяться временем чтения из RAM в кеш процессора.
Не-не-не…

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

Послав несколько десятков тысяч хешей с разными первыми символами можно определить при каком первом символе средняя задержка максимальна и тем самым узнать первый символ. Затем — второй. И т.д.

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

Эффект аналогичен введению произвольной задержке после сравнения каждого символа, но при этом не будет нагружать сервер холостыми операциями, а вычленить злоумышленнику полезную информацию из задержек будет не только дольше, но и сложнее.
Обычно так не делают, сверяют всё одним махом и только потом выдают ответ, потому что операция сравнения это линейная арифметика которая хорошо конвейеризируется, а проверка условия на каждой итерации сравнения — это смерть конвейеризации и деградация скорости. Проверка без условия внутри цикла может оказаться в 100 раз быстрее чем проверять каждый байт отдельно и выдавать ответ досрочно. Кроме того, выборка из памяти в кеш операция несравнимо более долгая чем выполнение инструкций сравнения, даже сотня сравнений может не сравнится с выборкой одного байта из RAM по времени. На фоне доступа к RAM отличие длительности выполнения алгоритма для разных условий может оказаться на уровне погрешности измерения.
На более простых чипах с криптографией такое вполне удавалось проделать, вплоть до анализа потребления чипом делались предположения какая инструкция исполняется и по какой ветви алгоритма процессор пошел, из чего делались выводы о содержимом регистров, памяти и т.д. но с современными процессорами такое проделать уже не реально.
Подпись — это MD5 от строки, состоящей из общего секрета и добавленных за ним следом пар ключ-значение.

Хмм… мне казалось, что обычно под подписью подразумевается, зашифрованное секретом, MD5 от строки с данными, а не MD5 от секрета + данные. Хотя моя компетентность находится где то между 1 и 2, так что я не претендую :)
Ваш способ требует два криптопримитива (хеш и симметричный шифр).
Чисто академически интереснее решение, как можно более простое, но не менее надёжное.
Но статья об использовании криптографии в реальной жизни, а не в академических изысканиях.

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

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

Я уверен, что до определённого времени вариант MD5(key | message) был вполне себе «паттерном». Примеры Flickr, Vimeo и RTM нам на это как бы намекают.
Поэтому используйте Кетчак или Sha256|512 :D
Разные хеш-функции погоды не сделают. Речь идет о несовершенстве алгоритма их использования
Для Keccak (sha3) length extension attack не работает (по крайней мере в лоб).
Интересно, а атаке Length extension attack подвержена смена местами данных и секрета (постфиксное положение секрета)?
Конкретно от угрозы length extension это избавит.

Но у варианта H(message | key) есть свои проблемы. В частности, поскольку message (а значит и его хэш) взломщику известен, он может найти такое сообщение message2, которое будет давать то же самое значение хэша: H(message) = H(message2). А значит и после приклеивания в конце ключа хэши будут совпадать. Т.е. подпись от message можно будет использовать для отправки message2.

Вариант H(key | message | key) — лучше. Но и у него были обнаружены уязвимости, даже когда ключ-префикс и ключ-суффикс различаются.

Упоминаемый в статье HMAC использует, на самом деле, схему H(key1 | H(key2 | message)), где key1 и key2 особым образом получаются из исходного ключа.
Ну все-таки, найти два разных сообщения, дающих одинаковый хэш весьма затруднительно насколько я знаю.)
В случае MD5 вполне реально найти два СЛУЧАЙНЫХ блока, дающих одинаковый хэш, отличающихся всего на пару битов. А мы говорим о подборе пары для заведомо известного блока, а такое даже MD5 себе не позволяет)
Вы по ссылке-то ходили?
В 2005 исследователи смогли создать пару PostScript документов, имеющих одинаковый MD5-хэш, а также пару X.509 сертификатов с совпадающим хэшем.
А в 2008 обычный SSL-сертификат был успешно превращён в рабочий CA-сертификат якобы от имени того же самого провайдера.
То о чем вы говорите элементарно сделать, имея два блока, порождающих коллизию. Я просто когда то интересовался этим вопросом. Если интересно, вот мой давний пост о том как это можно сделать самостоятельно habrahabr.ru/post/113127/
Хорошо, с парами файлов всё понятно.
Но как по-вашему они сертификат меняли? Или вы думаете, что там они тоже сначала сгенерировали пару _случайных_ блоков?

Пишут, кстати, что для взлома использовали кластер из примерно 200 Sony PS3, который работал 3 дня. И это в 2008 году! Спустя два года после описанного в вашем посте:
в 2006 году чешский криптограф Властимил Клима предложил для поиска коллизий новый метод, позволяющий найти разную пару случайных 128 байтных блоков с одной md5 суммой на персональном компьютере меньше чем за минуту

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

Во-первых, есть так называемая collision resistance, а есть preimage resistance. И хотя эти понятия легко перепутать, отличия весьма существенны.
Так, collision resistance это способность хэш-функции противостоять случайным коллизиям, т.е. применительно к MD5 ни о какой collision resistance говорить не приходится.
А вот preimage resistance это уже как раз то, о чем мы с вами в данный момент спорим, т.е. способность найти по данному x такое x`, что x`!=x, но H(x`)=H(x). Так вот такие атаки на MD5 известны, конечно но они очень затратны. По той же ссылки, которую вы любезно привели выше, написано:
In April 2009, a preimage attack against MD5 was published that breaks MD5's preimage resistance. This attack is only theoretical, with a computational complexity of 2123.4 for full preimage.

Сами понимаете, тут никакой кластер не спасет.

Во-вторых, атаки на collision resistance подразделяются в свою очередь на два вида Classical collision attack и Chosen-prefix collision attack. Так вот, атаки первого типа на MD5 не требуют практически никаких усилий. Коллизии находятся даже на не самом сильном ПК за считанные секунды. К сожалению они неприменимы для подделки SSL-сертификатов, в силу особой структуры файлов.
Но к счастью или несчастью, как посмотреть, есть еще Chosen-prefix collision attack, сложность которой для MD5 составляет примерно 250.
Так что нет, я не думаю что им просто захотелось погонять кластер.) Просто, продемонстрировали практическую реализацию Chosen-prefix collision attack.
Вернёмся теперь к тому, с чего это ветка начиналась.
У вредителя есть сообщение message1 и его валидная подпись. На основании этого он генерирует новое сообщение message2, которому будет подходить та же самая подпись.
Ну оставит он неизменным тот же самый «chosen-prefix», а потом (за счёт 250) добавит к нему какой-то мусорный параметр, в который спрячет все лишние байты, а вместе с ним ещё один параметр типа «action=delete».

Вот и получается, что перехватив сообщение message1 = «action:add ...» его можно превратить в message2 = «action:add… action:delete ...», имеющее ту же самую подпись.
Что это, как не та самая проблема схемы H(message | key), о которой я писал выше?
В H(message|key) как раз этой проблемы нет. Она есть в схеме (key|message), где мессадж можно растягивать, т.к. он последний.

«В частности, поскольку message (а значит и его хэш) взломщику известен, он может найти такое сообщение message2, которое будет давать то же самое значение хэша: H(message) = H(message2). А значит и после приклеивания в конце ключа хэши будут совпадать»

а это preimage, а не (chosen-prefix) collision
Постойте. Речь не шла о length extension attack на H(key | message)
Там ведь и коллизий-то никаких не надо — растянул сообщение, обновил хэш и отправил на сервер (уже с _новой_ подписью)

А в схеме H(message | key) как раз за счёт коллизий можно подменить message, оставив подпись без изменений. О том и речь была:
Конкретно от угрозы length extension это избавит. Но у варианта H(message | key) есть свои проблемы. ...


(может быть, я некорректно назвал это «chosen prefix»-ом в предыдущем своём комментарии)
Да, вы некорректно назвали это «chosen prefix», т.к. это классический пример preimage взлома. Создать пару для message, такую что H(message)=H(message2). Это уже не коллизия, это именно второй прообраз. Мне кажется вы не улавливаете разницу.
вот именно об этом и речь, вы назвали это chosen prefix, а это «chosen postfix», т.к. ключ в конце. И атака превращается в preimage, которая сложная как 2^123
Вы правы. Разобрался с chosen prefix / preimage. Спасибо.

Но, насколько я понимаю, это всё равно не отменяет уязвимости схемы H(message | key):
appending the key using MAC = H(message | key), suffers from the problem that an attacker who can find a collision in the (unkeyed) hash function has a collision in the MAC

Именно о ней я и писал в самом начале этой ветки.
Собственно, потому в HMAC и выбрали другую схему — H(key1 | H(key2 | message))
посыл статьи… носит слегка рекламный оттенок («оставьте криптографию нам, экспертам»)

в комментариях к статье автор явно говорит, что сам не является экспертом по криптографии.
Но можем ли мы слепо веровать, что это его собственный посыл, или же скорее мы опасно некомпетентны в маркетинговом FUD?
Инетерсно, но сильно преувеличено эмоционально. В безопасности меня не устает поражать гигантская пропасть между теоретической криптографией в вакууме и каким-нибудь практическим экспертом вроде Ganesh Krishnan, который с докторской степенью и 20-ю годами работы в качестве главного безопасника не где-нибудь, а в Yahoo и LinkedIn, умудрялся тупо хранить пароли без соли.

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

Потом приезжаешь ты к клиенту в командировку, и что: стандартный браузер IE7, где есть огнелис, он говорит что flash устарел до такой степени, что лиса уже его отключила, а пароли вообще сохраняются в винде…
Ну как тут не вспомнить требования одной милой компании по полной отчетности о процессе разработки ПО, включая ISO 13485, FDA Part 11, HIPAA и прочие КПСС, валидации партнерами всего софта вплоть до Экселя включительно (!!!)… и неубиваемый внутренний корпоративный стандарт на использование IE 6. Стоял 2010 год…
В принципе, все это уже далеко не откровения. Но напоминать себе об этом никогда не лишне, а то бывают иногда сомнительные мысли чего-нибудь своего этакого изобрести.
P.S. кто еще на Matasano Crypto Challenges подписался?)
йа :) решил за пару часов первый пак, жду второй ^_^
Очередное доказательство аксиом:

1. Криптография по-прежнему остаётся больше математикой, нежели программированием.
2. Стойкость криптографии смягчается безмозглостью пользователей.


Самое печальное (и это отмечается в статье), что некомпетентность в вопросах криптографии имеет место даже в компаниях-гигантах вроде Yahoo и LinkedIn. Придётся сформулировать и запомнить третью аксиому: (не)серьёзность отношения к криптографии не зависит от именитости компании.
А иногда рядом даже known_hosts лежит
Гениально! Я про безмозглость пользователей
Против атаки по времени – можно сравнивать хеши 2х строк.
А если сделать вот так:
md5(md5($secret.'foo:bar').$secret.'foo:bar');

Сам я не имея никаких знаний о криптографии уже 3 года использую: md5($this->o['secret_part1']. md5($mes. $this->o['secret_part2']. $this->id));
$this->o['secret_part1'] и $this->o['secret_part2'] естественно уникальны и строго зависят от $this->id.
Да я некомпетентен в вопросах криптографии и много чего еще незнаю. Но параноик внутри меня всегда не доверял простому хешу md5 в условиях растущей производительности вычислительных машин.
Навскидку:
1) если вы результат вычисления сравниваете обычным == — timing attack, получите и распишитесь
2) пример у вас в первом абзаце выглядит лучше*, чем тот вариант, что вы «используете уже 3 года»
если в вашем внутреннем вызове md5($mes. $this->o['secret_part2']. $this->id) заменить значение $mes на другое, имеющее такой же хэш, подпись по-прежнему будет валидной

* в общем-то, защищённый от extension-атак HMAC использует очень похожую схему: H(key1 | H(key2 | message))
сравниванию ===, но там еще ждать ответа от базы данных и в месте с пингом думаю сложно тайминг атаку сделать. Хотя, прочитав вашу статью руки чешутся, на локальном проекте попробовать сделать)). В моем случае $mes — это короткое 32битное сообщение разделенное спец символами с проверкой валидации, передается строкой в 16 байт. Поэтому не думаю кому-то подфартит с секретными ключами настолько, чтобы провести атаку и пройти валидацию.

Благодарен за ответ, обязательно буду использовать ваш опыт.
PS. вот сейчас подумал. Ведь так как md5 хеш имеет ограниченную длину, то вероятность получить нужный нам $mes(тот при котором подпись останется такойже) простым перебором функции md5(md5($secret1.$mes).$secret2.$mes') с разным сообщением примерна равна и md5($mes. $this->o['secret_part2']. $this->id) Разниться только в нужных мощностях для перебора.
… думаю сложно тайминг атаку сделать. Хотя, прочитав вашу статью руки чешутся, на локальном проекте попробовать сделать
см. выше и ветку вниз — не могу даже тенденцию выявить.
Мы обычно к HMAC добавляем таймстемп. Во-первых защищает от отложенных атак (reply), во-вторых защищает от бесконечного брутфорса.

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

С криптографией так же. Зайти и взять по http плейнтекстом — это одно (не наказуемо, «по понятиям»). Взломать шифр — это уже откровенная агрессия.

Да и сравните сложность «пойти и взять» с «арендовать сервер в том же ДЦ и устроить гигантскую timing-атаку».

Криптографическое «всё или ничего» спокойно сглаживается «мне 500 грамм того, и вот того, и ещё сверху столько же», после чего система становится более-менее для практических целей защищённой.
Зайти и взять по http плейнтекстом — это одно (не наказуемо, «по понятиям»).

Статья та же, что и при атаке на TLS. Никого не волнует метод, важен лишь результат. Если у вас была распахнута стальная дверь, в доме никого не было, к вам зашли и вынесли телевизор, то это то же самое, что и «взломать замок».
арендовать сервер в том же ДЦ и устроить гигантскую timing-атаку

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

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

И часы синхронизируете по защищённому протоколу? Всё как положено?

Не совсем понятно, как это защищает от «бесконечного брутфорса»?
Насколько я понял, вы говорите о том, что клиент добавляет к запросу временную метку, а сервер пропускает только те запросы, у которых метка не сильно отличается от ожидаемой? (HMAC здесь тогда особо и ни при чём)
Что мешает «брутфорс-клиенту» обновлять эту метку в своих запросах с какой-то периодичностью? (лишь бы попадала в «окно сравнения»)
Что-то я торможу, извините. Конечно, «брутфорс-клиент» не может обновить временную метку, потому что она подписана вместе со всем сообщением (тем самым HMAC).
В нашем случае HMAC-сообщение используется для доказательства, что А и Б — это одно и то же. Читай — А запросил (по доверенному каналу), мы выдали подписанное. Б предъявил, мы ему поверили.

Интрига ещё сложнее, с учётом, что сообщение для А выдаёт один сервис, а проверяет у Б — другой. Между обоими сервисами общий секрет, плюс более-менее синхронизированное время.

Часы синхронизируются с местечкового NTP по серой сетке, с которого синхронизируются все dom0, а виртуалки доверяют гипервизору, на котором запущены.
И часы синхронизируете по защищённому протоколу? Всё как положено?
Мне кажется, что мы можем допустить рассинхронизацию часов между клиентом и сервером на некоторое количество минут m. Если клиентский timestamp вылезает за этот порог, то считаем его невалидным. Если не вылезает, то проверяем список HMAC запросов от этого клиента за последние 2m минут. Если нашли совпадение, то это replay-атака. Если не нашли, то можем выполнить запрос.
вот прям браво!

за время своего аспирантства чего только не видел… и ведь верят люди, что изобрели «принципиально новый алгоритм» и седые дядьки им в ответ головой кивают. Шнайер метко называет это «псевдонаучной болтовней»: некомпетентный изобретатель + некомпетентный слушатель = восторженная околонаучная возня.

«не знаешь — не лезь», в граните бы высек эти слова.
Как вы думаете, Тьюринг, который ломал Энигму — он «знал»? или «полез не зная»? Любой другой учёный — он знал или нет?

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

Грубо говоря, откуда появилось то знание, которым теперь жирно потряхивают эксперты? Было спущено на каменных скрижалях по вертикали власти? Приснилось пророку и с тех пор все строго следуют?

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

Желание — оно, безусловно, похвально, однако «не знаешь — не лезь» не значило «не знаешь — не старайся узнать».
На пальцах:
Знаешь? точно? посмотри сюда, сюда и сюда и подумай еще раз.
Все еще считаешь, что умеешь? Ну тогда не обижайся.
Почему здесь сказали про абсолютно нереализуемую в этом случае тайминг атаку и забыли про очень даже реальную replay атаку? Если схема аутентификации не предусматривает создания сессии с пронумерованными сообщениями, атакующий может запомнить и повторить действия клиента. Это во многих случаях эквивалентно получению доступа.
Коль пошла такая пьянка, хочу снова попробовать обратиться к экспертам, если здесь такие присутствуют.

Есть такая OpenSource программа MyTetra. Данные пользователя могут храниться на открытых для всех на чтение бесплатных Git-репозитариях, например на GitHub.com. Приватные данные шифруются с помощью самописной библиотеки RC5Simple.

Схема шифрования следующая:

Данные шифруются по алгоритму RC5-32/12/16 c CBC-режимом сцепления (библиотека RC5Simple), ключ генерируется на основе пароля с солью, пропущенного через алгоритм PBKDF2 на 1000 раундов с длиной ключа 160 бит. Для генерации ключа шифрования в 128 бит, от результата берется MD5 сумма. Каждая запись шифруется с уникальным инициализирующим вектором.

Хотелось бы оценить две вещи:

1. Правильность реализации RC5. Сама библиотека RC5Simple имеет всего 20Кб C++ кода. Хотелось бы провести ревизию кода/алгоритма специалистом, который разбирается в вопросе.

2. Оценка стойкости данного метода шифрования. Меня беспокоит тот факт, что открытый текст всех зашифрованных записей одинаковый — обычный HTML заголовок. В принципе, он конечно перемешивается за счет инициализирующего вектора (другими словами — соли), но вектор хранится ведь в открытом виде. Поэтому, сверху накладывается PBKDF2. Достаточно ли этого всего для того, чтобы при хорошем пароле на современных средних мощностях невозможно было подобрать пароль ну пусть в течении 100 лет?

Я уже обращался к экспертам на Хабаре:
http://habrahabr.ru/post/124090/#comment_4089407
но в ответ была только отписка.
Я не эксперт, но на месте эксперта мне было бы лень…
Sign up to leave a comment.

Articles