Как я могу: генерировать 40/64 битный ключ WEP в Python? - PullRequest
4 голосов
/ 23 мая 2010

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

То, что я пытаюсь сделать, это, как следует из заголовка, генерировать 40/64-битный ключ WEP из ключевой фразы, в соответствии со стандартом "де-факто". (Сайт, такой как http://www.powerdog.com/wepkey.cgi, производит ожидаемые результаты.) Я уже написал части скрипта, которые принимают входные данные и записывают их в файл; одним из входных данных будет фраза-пароль, очищенная в нижнем регистре.

Долгое время я понятия не имел, что такое стандарт defacto, тем более, как его реализовать. В конце концов я наткнулся на статью (http://www.lava.net/~newsham/wlan/WEP_password_cracker.pdf), которая проливает столько же света, сколько у меня было до сих пор (вопрос содержит соответствующие биты). По-видимому, фраза-пароль «сопоставляется с 32-битным значением с помощью XOR, «результат которого затем используется в качестве начального числа для» линейного конгруэнтного PRNG (который один из нескольких PRNG Python будет соответствовать этому описанию, я не знаю), а затем из этого результата несколько битов результата Я не знаю, как это осуществить, так как описание довольно расплывчато.

Мне нужна помощь в написании генератора на Python, а также в понимании того, как именно генерируется ключ. Другими словами, мне нужен код, чтобы превратить «Джексон» в «09F38AF593». (И, пожалуйста, не говорите мне, Джексон = 09F38AF593; печать (Джексон))

Я не очень программист, поэтому объяснения также приветствуются.

(Да, я знаю, что WEP небезопасен.)

Ответы [ 2 ]

5 голосов
/ 23 мая 2010

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

В любом случае, к коду.

import itertools, operator

Во-первых, генератор псевдослучайных чисел, который был обозначен в представлении как линейный конгруэнтный генератор .Этот тип PRNG является общим алгоритмом, который можно «настраивать», выбирая конкретные значения a, c и m (переменные, упомянутые в статье Википедии).Вот реализация универсального линейного конгруэнтного генератора:

def prng(x, a, c, m):
    while True:
        x = (a * x + c) % m
        yield x

(надеюсь, вы могли бы придумать это самостоятельно)

Теперь для фактической функции:

def pass_to_key(passphrase):

Первым шагом в этом процессе является хэширование (или «отображение») парольной фразы, предоставленной для 32-битного числа.Алгоритм WEP делает это путем создания набора из 4 байтов (таким образом, 4 * 8 = 32 бита), которые инициализируются в ноль.

    bits = [0,0,0,0]

Он проходит через строку и XOR каждый символ с одним из байтов;в частности, символ i переводится в XOR в байт i % 4.

    for i, c in enumerate(passphrase):
        bits[i & 3] ^= ord(c)

Затем эти четыре байта объединяются вместе, чтобы сформировать одно 32-битное значение.(В качестве альтернативы я мог бы написать код для хранения их в виде 32-разрядного числа с начала)

    val = reduce(operator.__or__, (b << 8*i for (i,b) in enumerate(bits)))

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

    keys = []

Линейный конгруэнтный генератор может производить до 32 битов вывода одновременно.(В C это ограничение типа данных; в Python мне пришлось принудительно применять его.) Мне нужно 20 байтов для генерации 4 40-битных (5-байтовых) ключей WEP, поэтому я буду повторять PRNG 20 раз,

    for i, b in enumerate(itertools.islice(prng(val, 0x343fd, 0x269ec3, 1<<32), 20)):

и от каждого числа берите только третий байт справа (биты 16-23):

        keys.append((b >> 16) & 0xff)

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

После этого остается толькораспечатать сгенерированные байты в группах по 5 *. 1041 *

    print ('%02x:%02x:%02x:%02x:%02x\n'*4) % tuple(keys)
1 голос
/ 23 мая 2010

Я не уверен, о каком "стандарте де-факто" идет речь на этом сайте, но я уверен, что все производители маршрутизаторов используют свои собственные методы. Неважно, как вы это делаете, если один и тот же ввод всегда приводит к одному и тому же выводу; Это удобно, поэтому пользователи WEP могут запомнить ключевую фразу вместо фактического шестнадцатеричного ключа. Даже метод в PDF, который вы разместили, в значительной степени неоднозначен; он использует неопределенный PRNG (и каждый тип PRNG будет давать различный результат) и берет «один байт» из каждого результата, не указывая, какой именно. Если вы пытаетесь провести обратный инжиниринг метода конкретного маршрутизатора, упомяните об этом в посте, и мы сможем узнать, как он работает, но стандартного метода не существует

...