Шифрование 30-битного числа в 6-символьную буквенно-цифровую строку - PullRequest
2 голосов
/ 10 июля 2011

Я ищу подход для шифрования / обфускации 30-битного числа.

Результаты будут сгруппированы в наборы по 3 и видимы для пользователей в виде 6-значного алфавитно-цифрового кода, закодированного в алфавите base32, но пользователь не должен иметь возможность выбрать шаблон в буквенно-цифровых строках.Например, пользователи могут видеть 3 строки: ASDFGH, LKJHGF, ZXCVBN, и они могут отображаться на номера 1073741821, 1073741822, 1073741823. Но это шаблон, который они не могут легко понять.

Я рассмотрел несколько алгоритмов шифрования, например, DES.Вот плохая и наивная попытка:

import struct
from Crypto.Cipher import DES
from .baseconv import base32_urlsafe

_KEY = '\x81\x98\xe1\x14<\xb3\xe8\x10'
_encryptor = DES.new(_KEY)

def encrypt_number(number):
    encrypted_i64 = struct.unpack(
        '!Q', _encryptor.encrypt(struct.pack('!Q', number))
    )[0]
    encrypted_i30 = encrypted_i64 >> 34
    return base32_urlsafe.encode(encrypted_i30)

Но, очевидно, я не смогу расшифровать строку, если она когда-либо понадобится, и уникальность при таком подходе теряется.Также рассматривал использование XOR, но это слишком предсказуемо, поскольку чаще цифры не будут иметь последовательную последовательность.

Мне никогда не приходилось кодировать что-то подобное.Итак, я ищу некоторые алгоритмы шифрования / подходы для исследования и рассмотрения.Я использую python, но приветствуются идеи или примеры, использующие другие языки.

Ответы [ 3 ]

7 голосов
/ 10 июля 2011

Здесь может быть полезно шифрование с сохранением формата .

Например, метод обхода цикла, описанный в статье Блэка и Рогэвея "Шифры с произвольными конечными доменами", кажется потенциальнымрешение.Например, используйте 32-битный шифр (например, Skip32 от Greg Rose).Зашифруйте ваш 30-битный ввод с помощью шифра.Если результатом является 30-разрядное целое число (т. Е. Первые 2 бита равны 0), то все готово, в противном случае продолжайте шифрование с помощью шифра, пока не получите 30-разрядный результат.Расшифровка производится соответственно.

Если вам не нужно очень безопасное решение, тогда может быть альтернативой шифр Hasty Pudding .Он может зашифровать входные данные произвольного размера.Он был представлен на конкурс AES, однако не очень далеко продвинулся и, следовательно, не был хорошо проанализирован.Тем не менее, я ожидал бы, что это будет намного более подходящим, чем любые специальные решения, предлагаемые здесь на stackoverflow.

1 голос
/ 11 июля 2011

Просто сверните свой собственный 30-битный блочный шифр, используя конструкцию Luby-Rackoff .

Используйте любую хеш-функцию, которую вы хотите для блоков "F" (например, младшие 15 битов)из ропота ваших данных плюс секретный ключ) и запустите столько раундов, сколько захотите, и результатом будет обратимая псевдослучайная перестановка на 30-битных числах.

Конечно,оно не будет «криптографически сильным», но с 30 битами ничего не может быть.

1 голос
/ 10 июля 2011

Один из подходов состоит в том, чтобы иметь таблицу с 1B (2 ^ 30) уникальными случайными числами - и использовать ваше 30-битное число в качестве индекса в этой таблице.

Если эта таблица слишком большая, вы можете создать меньшую - скажем, 32768 записей и индексировать нижнюю половину и верхнюю половину отдельно.

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

Шифрование

t = table of 32768 random values    
upper15 = input_value >> 15    
lower15 = input_value & 0x7FFF    
lowercoded = t[lower15]    
uppercoded = t[ ( lowercoded + upper15 ) % 32768 ]    
result = uppercoded << 15 + lowercoded

1010 * дешифрования * upper15 = input_value >> 15 lower15 = input_value & 0x7FFF lowereddecoded = t.index(lower15) tmp = t.index(upper15) tmp -= lower15 if tmp< 0: tmp += 32768 upperdecoded = tmp result = upperdecoded << 15 + lowerdecoded

...