重构此分组密码密钥功能

ʞɔı*_*ɔıu 1 python encryption

我找到了一个简单的纯python blowfish实现,它满足了我对特定项目的需求.

只有一部分困扰我:

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"
Run Code Online (Sandbox Code Playgroud)

subkey = eval('0x'+hexkey[pos:pos+8]+'L')?请告诉我有更好的方法来做到这一点.

难道没有办法重构这个以使用实际的整数类型而不是字符串中的十六进制值吗?

Bri*_*ian 5

是.使用基数为16的int().

>>> int('ffffffff',16)
4294967295L
Run Code Online (Sandbox Code Playgroud)

所以:

subkey = int(hexkey[pos:pos+8], 16)
Run Code Online (Sandbox Code Playgroud)

应该做同样的事情而不需要eval.

[编辑]事实上,在给定整数的情况下,通常没有理由需要转换为字符串表示 - 您可以通过ANDing简单地提取每个32位值0xffffffff并将键右移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)
Run Code Online (Sandbox Code Playgroud)

然而,这个初始化过程似乎有点奇怪-它使用从左边开始,16进制数,没有填零舍入到8个十六进制数字的倍数(这样的数量0x123456789将被分裂成0x123456780x9,而不是更习惯0x000000010x23456789.它也会重复这些数字,而不是将其视为单个数字.您应该检查此代码是否实际执行了正确的算法.