Рефакторинг функции блочного шифрования - PullRequest
1 голос
/ 15 июня 2009

Я нашел простую реализацию 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"

subkey = eval('0x'+hexkey[pos:pos+8]+'L')? Пожалуйста, скажите мне, что есть лучший способ сделать это.

Нет ли способа изменить его, чтобы использовать фактический целочисленный тип, а не шестнадцатеричные значения в строке?

Ответы [ 4 ]

5 голосов
/ 15 июня 2009

Да. Используйте int () с основанием 16.

>>> int('ffffffff',16)
4294967295L

так:

subkey = int(hexkey[pos:pos+8], 16)

должен делать то же самое, не нуждаясь в eval.

[Редактировать] На самом деле, вообще нет причин, по которым вам вообще нужно преобразовывать в строковое представление, учитывая целое число - вы можете просто извлечь каждое 32-битное значение, используя AND с помощью 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)

Однако этот процесс инициализации кажется немного странным - он использует шестнадцатеричные цифры, начинающиеся слева, без дополнения нулями для округления до кратных 8 шестнадцатеричным цифрам (поэтому число 0x123456789 будет разбито на 0x12345678 и 0x9, а не более привычные 0x00000001 и 0x23456789. Он также повторяет эти числа вместо того, чтобы рассматривать его как одно большое число. Вам следует убедиться, что этот код действительно выполняет правильный алгоритм.

3 голосов
/ 15 июня 2009

Не используйте этот код, тем более пытайтесь его улучшить.

Использование криптографического кода, найденного в Интернете, может привести к серьезным сбоям в безопасности вашего программного обеспечения. См. небольшую серию Джеффа Этвуда на эту тему.

Гораздо лучше использовать проверенную криптобиблиотеку на самом высоком уровне абстракции. Идеально тот, который реализует всю обработку ключей в C и заботится об уничтожении ключевого материала после использования.

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

1 голос
/ 15 июня 2009

Альтернативой является "int ('0x111', 0)". Вторым аргументом int является база. «0» означает «использовать обычные правила: ни один префикс не является десятичным, префикс 0 - восьмеричным, а 0x - шестнадцатеричным - как и eval».

Это предпочтительный способ «эмулировать» операцию eval для заражения строк.

0 голосов
/ 15 июня 2009

Вы можете сделать это с помощью длинной функции:

subkey = long(hexkey[pos:pos+8], 16)  

С help(long):

класс long (объект)
| long (x [, base]) -> целое число
|
| Если возможно, преобразуйте строку или число в длинное целое число. Плавающий
| аргумент точки будет обрезан до нуля (сюда не входит
| строковое представление числа с плавающей точкой!) При преобразовании
| строка, используйте необязательную базу. Ошибка в предоставлении базы, когда
| преобразование не-строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...