Если открыть предложенную программу в декомпиляторе(.NET Reflector), видим следующее:
![]()
Яркий пример неправильного использования криптоалгоритмов, вместо стойкого Rijndael используется сложение по модулю два с результатом шифрования переменной, которая передается в программу для использования в качестве IV. Как мы знаем, шифрование с помощью операции XOR обладает абсолютной стойкостью только при условии однократного использование ключа большей или равной длины чем шифротекст итд. Если один и тот же ключ используется дважды, то атакующий может его найти.
Изучив формат транзакции мы видим, что она состоит из блоков размером 16 байт, а 3, 5 итд блоки содержат информацию о сумме транзакции, которая имеет четкую структуру.
Обозначим функцию шифрования Rijndael как F(x), тогда ключем для XOR в первом блоке будет F(x), во втором F(F(x)) итд.
Сравнивая результат двукратного F(x) от побайтного XOR перебираемого значения информации о сумме транзакции и 3 блока данных в качестве ключа с имеющимися шаблонами данных имеем возможность найти ключ XOR, а затем и параметр "IV". Пример реализации решения прилагается. Возможно задачу можно было решить более эффективно, хотелось бы услышать варианты.
CTF → Решение для crypto 300 на ruCTF quals 2010
No TrackBacks
TrackBack URL: http://smokedchicken.org/m/mt-tb.cgi/19
Не совсем верно, на счет нестойкости XOR-а. Абсолютной стойкости никто не просит, 256 бит достаточно на ближайшие N десятков лет.
На самом деле, прога просто реализовывала классический режим использования блочного шифра OFB (http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29). Реализовывала руками потому, что несмотря на то, что в .NET-овских наследниках SymmetricAlgorithm-а предусмотрен CipherMode.OFB, но во всех этих наследниках он не поддерживается :) - пришлось делать OFB руками.
Цель таска была продемонстрировать нестойкость блочного шифрования в режиме OFB, при знании ключа и знании структуры с возможностью быстрого нахождения хоть одного блока открытого текста перебором.
если бы на входе F(x) каждого нового цикла был результат F(x) от предыдущего цикла XOR plaintext, это был бы OFB, здесь же в F(x) всегда подается только результат от F(IV).
шифрование только XOR'ом стойко в одном случае - см. Шеннона :)
прошу прощения, действительно всё так как вы написали ) перепутал с CFB