所以,我几个月来一直在打破这个问题的障碍,部分原因是因为这是一个副作用,部分是因为我很喜欢编程.我在网上搜索和研究过,但没有任何运气(除了一点点成功;见下文),所以我想我可能会尝试询问专家.
正如标题所示,我想要做的是根据"事实上的"标准从密码短语中生成一个40/64位的WEP密钥.(诸如http://www.powerdog.com/wepkey.cgi之类的站点产生预期的输出.)我已经编写了部分脚本来获取输入并将它们写入文件; 其中一个输入是密码,清理为小写.
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.
我需要的是帮助用Python编写生成器,以及理解密钥的生成方式.换句话说,我需要代码将"jackson"变成"09F38AF593".(请不要告诉我杰克森= 09F38AF593;打印(杰克逊))
我不是一个程序员,所以解释也很受欢迎.
(是的,我知道WEP不安全.)
您链接到的C代码非常有助于包含在问题中;-)无论如何,我继续将其翻译成Python.在您阅读之前,请允许我说我强烈建议您自己尝试并仅使用我的转录作为指导.当您希望提高一种或两种语言的技能时,将算法从一种编程语言转换为另一种编程语言通常是很好的做法.即使你不懂C,只要你熟悉Python就可以编写程序,你应该能够获得C代码的要点,因为它有许多相似之处.
无论如何,对代码.
import itertools, operator
Run Code Online (Sandbox Code Playgroud)
首先,伪随机数生成器,在演示中被识别为线性同余生成器.这种类型的PRNG是一般的算法通过选择的特定值可以被"定制" a,c和m(维基百科文章中提到的变量).这是一个通用线性同余生成器的实现:
def prng(x, a, c, m):
while True:
x = (a * x + c) % m
yield x
Run Code Online (Sandbox Code Playgroud)
(希望你能自己想出来)
现在为实际功能:
def pass_to_key(passphrase):
Run Code Online (Sandbox Code Playgroud)
该过程的第一步是散列(或"映射")提供给32位数字的密码短语.WEP算法通过创建一组4字节(因此4*8 = 32位)来初始化为零来完成此操作.
bits = [0,0,0,0]
Run Code Online (Sandbox Code Playgroud)
它通过字符串和每个字符的XOR与一个字节; 具体来说,字符i与字节进行异或i % 4.
for i, c in enumerate(passphrase):
bits[i & 3] ^= ord(c)
Run Code Online (Sandbox Code Playgroud)
然后将这四个字节按顺序连接在一起,以形成单个32位值.(或者,我可以编写代码将它们从头开始存储为32位数字)
val = reduce(operator.__or__, (b << 8*i for (i,b) in enumerate(bits)))
Run Code Online (Sandbox Code Playgroud)
这个32位值用作线性同余生成器的种子,具有某些特定值,您可以在代码中看到这些值.原始开发者如何找出这些数字,我不知道.
keys = []
Run Code Online (Sandbox Code Playgroud)
线性同余生成器一次最多可以产生32位输出.(在C中,这是数据类型的限制;在Python中我必须人为地强制执行它.)我需要20个字节来生成4个40位(5字节)WEP密钥,所以我将重复PRNG 20次,
for i, b in enumerate(itertools.islice(prng(val, 0x343fd, 0x269ec3, 1<<32), 20)):
Run Code Online (Sandbox Code Playgroud)
从每个数字中,只取右边的第3个字节(第16-23位):
keys.append((b >> 16) & 0xff)
Run Code Online (Sandbox Code Playgroud)
为什么第三个?那么,高端的位(右边的第4位)往往没有太大变化,而低端的位可以预测PRNG常数的许多值.
之后,剩下的就是以5个为一组打印出生成的字节.
print ('%02x:%02x:%02x:%02x:%02x\n'*4) % tuple(keys)
Run Code Online (Sandbox Code Playgroud)