如何:在 Python 中生成 40/64 位 WEP 密钥?

发布于 2024-09-02 23:21:44 字数 843 浏览 2 评论 0原文

所以,几个月来我一直在这个问题上绞尽脑汁,部分是因为这是我的副业,部分是因为我不擅长编程。我在整个网络上进行了搜索和研究,但没有任何运气(除了一点点成功;见下文),所以我想我可以尝试询问专家。

正如标题所示,我想做的是根据“事实上的”标准从密码生成 40/64 位 WEP 密钥。 (http://www.powerdog.com/wepkey.cgi 等网站会生成预期的输出。)我已经编写了接受输入并将其写入文件的脚本部分;输入之一是密码,已净化为小写。

在很长一段时间里,我不知道事实上的标准是什么,更不用说如何去实施它了。我终于偶然发现了一篇论文(http://www.lava.net/~newsham /wlan/WEP_password_cracker.pdf),它阐明了我对这个问题的了解(第 18 页有相关部分)。显然,密码短语“通过 XOR 映射到 32 位值”,然后将其结果用作“线性同余 PRNG”的种子(Python 拥有的几个 PRNG 之一符合此描述,我不知道)我不知道),然后从该结果中获取了一些结果,我不知道如何实现这个,因为

我需要的是用Python编写生成器的帮助 。换句话说,我需要代码将“jackson”转换为“09F38AF593”(请不要告诉我 jackson = 09F38AF593; print (jackson))

我不是一个程序员。 ,所以解释也很受欢迎

(是的,我知道 WEP 不安全。)

So, I've been beating my head against the wall of this issue for several months now, partly because it's a side interest and partly because I suck at programming. I've searched and researched all across the web, but have not had any luck (except one small bit of success; see below), so I thought I might try asking the experts.

What I am trying to do is, as the title suggests, generate a 40/64 bit WEP key from a passphrase, according to the "de facto" standard. (A site such as http://www.powerdog.com/wepkey.cgi produces the expected outputs.) I have already written portions of the script that take inputs and write them to a file; one of the inputs would be the passphrase, sanitized to lower case.

For the longest time I had no idea what the defacto standard was, much less how to even go about implementing it. I finally stumbled across a paper (http://www.lava.net/~newsham/wlan/WEP_password_cracker.pdf) that sheds as much light as I've had yet on the issue (page 18 has the relevant bits). Apparently, the passphrase is "mapped to a 32-bit value with XOR," the result of which is then used as the seed for a "linear congruential PRNG (which one of the several PRNGs Python has would fit this description, I don't know), and then from that result several bits of the result are taken. I have no idea how to go about implementing this, since the description is rather vague.

What I need is help in writing the generator in Python, and also in understanding how exactly the key is generated. In other words, I need code to turn "jackson" into "09F38AF593". (And please don't tell me jackson = 09F38AF593; print (jackson))

I'm not much of a programmer, so explanations are appreciated as well.

(Yes, I know that WEP isn't secure.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

意中人 2024-09-09 23:21:44

您链接到的 C 代码如果包含在问题中会非常有帮助;-) 不管怎样,我继续将其翻译成 Python。在您阅读之前,请允许我说,我强烈鼓励您亲自尝试,并且仅使用我的转录作为指导。当您想提高一种或两种语言的技能时,将算法从一种编程语言翻译成另一种编程语言通常是很好的做法。即使你不懂 C,只要你足够熟悉 Python 并用它编写程序,你应该能够理解 C 代码的要点,因为它们有很多相似之处。

无论如何,先上代码。

import itertools, operator

首先是伪随机数生成器,在演示中将其识别为线性同余生成器。这种类型的 PRNG 是一种通用算法,可以通过选择 acm 的特定值(提到的变量)来“定制”在维基百科文章中)。这是通用线性同余生成器的实现:(

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]

它遍历字符串并将每个字符与一个字节进行异或;具体来说,字符 i 与字节 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 为一组打印生成的字节。

    print ('%02x:%02x:%02x:%02x:%02x\n'*4) % tuple(keys)

That C code you linked to would have been awfully helpful to include in the question ;-) Anyway, I went ahead and translated it into Python. Before you read it, let me say that I highly encourage you to try it yourself and only use my transcription as a guide. Translating algorithms from one programming language to another is generally great practice when you want to boost your skills in one or both languages. Even if you don't know C, as long as you're familiar enough with Python to write programs in it, you should be able to get the gist of the C code, since there are many similarities.

Anyway, on to the code.

import itertools, operator

First, the pseudorandom number generator, which was identified in the presentation as a linear congruential generator. This type of PRNG is a general algorithm which can be "customized" by choosing specific values of a, c, and m (the variables mentioned in the Wikipedia article). Here is an implementation of a generic linear congruential generator:

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

(hopefully you could have come up with that on your own)

Now for the actual function:

def pass_to_key(passphrase):

The first step in the process is to hash (or "map") the passphrase provided to a 32-bit number. The WEP algorithm does this by creating a set of 4 bytes (thus 4*8=32 bits) which are initialized to zero.

    bits = [0,0,0,0]

It goes through the string and XORs each character with one of the bytes; specifically, character i is XOR'd into byte i % 4.

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

These four bytes are then concatenated together, in order, to form a single 32-bit value. (Alternatively, I could have written the code to store them as a 32-bit number from the beginning)

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

This 32-bit value is used as the seed for a linear congruential generator with certain specific values which you can see in the code. How the original developer figured out these numbers, I have no idea.

    keys = []

The linear congruential generator can produce up to 32 bits of output at a time. (In C this is a limitation of the data type; in Python I had to artificially enforce it.) I need 20 bytes to generate 4 40-bit (5-byte) WEP keys, so I'll iterate the PRNG 20 times,

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

and from each number, take only the 3rd byte from the right (bits 16-23):

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

Why the third? Well, the bits at the high end (4th from the right) tend not to change much, and those at the low end can be predictable for many values of the PRNG constants.

Afterwards, all that's left is to print out the generated bytes in groups of 5.

    print ('%02x:%02x:%02x:%02x:%02x\n'*4) % tuple(keys)
独闯女儿国 2024-09-09 23:21:44

我不确定该网站正在谈论什么“事实上的标准”,但我相当确定路由器制造商都实施了自己的方法。不管你怎么做,只要相同的输入总是产生相同的输出即可;这很方便,WEP 用户可以记住密码而不是实际的十六进制密钥。甚至您发布的 PDF 中的方法也很不明确;它使用未定义的 PRNG(每种类型的 PRNG 都会给出不同的结果),并从每个结果中获取“一个字节”而不指定哪个字节。如果您尝试对特定路由器的方法进行逆向工程,请在帖子中提及,我们也许能够找出该方法的工作原理,但没有标准方法

I'm not sure what "de facto standard" that website is talking about, but I'm fairly sure router manufacturers all implement their own methods. It doesn't matter how you do it, as long as the same input always results in the same output; it's a convenience so WEP users can remember a passphrase instead of the actual hex key. Even the method in the PDF you posted is largely ambiguous; it uses an undefined PRNG (and every type of PRNG is going to give a different result), and takes "one byte" from each result without specifying which. If you're trying to reverse engineer a particular router's method, mention that in the post and we might be able to find out how that one works, but there isn't a standard method

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文