我找到了一个简单的纯python河豚实现,它满足了我对特定项目的需求。
其中有一部分让我感到困扰:
def initialize(key):
"""
Use key to setup subkeys -- requires 521 encryptions
to set p and s boxes. key is a hex number corresponding
to a string of 32 up to 448 1s and 0s -- keylen says
how long
"""
# Note that parray and sboxes are globals that have been pre-initialized.
hexkey = hex(key)[2:]
if hexkey[-1]=='L':
hexkey = hexkey[:-1]
if len(hexkey)%2==1:
hexkey = '0'+hexkey
lenkey = len(hexkey)/8
if lenkey==0:
pos=0
# XOR key segments with P-boxes
for i in range(18):
if lenkey>0:
pos = (i%lenkey)*8 # offset into key gives subkey
subkey = eval('0x'+hexkey[pos:pos+8]+'L')
parray[i] ^= subkey # immediate XOR -- Python 2.0+ syntax
# encrypt 0-data, then keep re-encrypting and reassigning P-boxes
output = 0L
for i in range(0,17,2):
output = bfencrypt(output)
parray[i], parray[i+1] = output>>32, output & 0xFFFFFFFFL
# re-encrypt and reassign through all the S-boxes
for i in range(4):
for j in range(0,255,2):
output = bfencrypt(output)
sbox[i][j],sbox[i][j+1] = output>>32, output & 0xFFFFFFFFL
# print "Initialization complete"subkey = eval('0x'+hexkey[pos:pos+8]+'L')?请告诉我有更好的方法。
难道没有一种方法来重构它来使用实际的整数类型而不是字符串中的十六进制值吗?
发布于 2009-06-15 16:19:31
是。使用基数为16的int()。
>>> int('ffffffff',16)
4294967295L因此:
subkey = int(hexkey[pos:pos+8], 16)应该做同样的事情而不需要评估。
编辑--实际上,如果给定一个整数,一般不需要转换为字符串表示形式--您可以通过ANDing和0xffffffff提取每个32位的值,并在一个循环中将键右移32位。例:
subkeys = []
while key:
subkeys.append(key & 0xffffffff)
key >>= 32
if not subkeys: subkeys = [0] # Handle 0 case
subkeys.reverse() # Use same order as before (BUT SEE BELOW)然而,这个初始化过程似乎有点奇怪--它使用的是从左开始的十六进制数字,没有零填充到8十六进制数字的倍数(因此数字0x123456789将被拆分为0x12345678和0x9,而不是更传统的0x00000001和0x23456789。它也重复这些数字,而不是把它当作一个大的数字。您应该检查这段代码是否实际执行了正确的算法。
发布于 2009-06-15 19:00:14
不使用这段代码,更不用说改进它了。
使用互联网上发现的密码可能会在软件中造成严重的安全故障。关于这个主题,请参见杰夫·阿特伍德的小系列。
在尽可能高的抽象级别上使用经过验证的密码库要好得多。理想情况下,在C中实现所有密钥处理,并负责在使用后销毁关键材料。
在Python中执行密码的一个问题是,由于Python字符串的性质和垃圾收集过程,您无法控制内存中关键材料的扩散。
发布于 2009-06-15 16:22:27
另一种选择是"int('0x111',0)“。int的第二个论点是基础。"0“的意思是”使用通常的规则:没有前缀是十进制的,0前缀是八进制的,0x是十六进制的--就像eval一样“。
这是“模拟”用于初始化字符串的eval操作的首选方法。
https://stackoverflow.com/questions/996965
复制相似问题