Pull to refresh

Comments 8

PinnedPinned comments

P.S. Строка в utf-8 тут взята только для примера

Впринципе можно шифровать любые байты

Если заранее известно, что зашифрована валидная utf-8 строка, то простейший брутфорсер пишется на коленке минут за двадцать, и это я ещё даже не пытался анализировать алгоритм


Скрытый текст
def to_bits(data: bytes) -> list[int]:
    data_bits: list[int] = []
    for b in data:
        data_bits.extend(map(int, f'{b:08b}'))
    return data_bits

def to_bytes(data_bits: list[int]) -> bytes:
    return bytes(int(''.join(str(bit) for bit in bits), 2) for bits in [data_bits[i:i + 8] for i in range(0, len(data_bits), 8)])

def shifrator_bruteforce(data: bytes, start_seed: int = 0):
    from random import Random

    data_bits: list[int] = to_bits(data)  # [0, 1, 0, ...]

    rnd = Random()
    seed = start_seed
    while True:
        seed += 1
        rnd.seed(seed)
        mask = list(range(len(data_bits)))  # [0, 1, 2, ...]
        rnd.shuffle(mask)
        result_bits = [data_bits[i] for i in mask]
        try:
            yield seed, to_bytes(result_bits).decode("utf-8")
        except UnicodeDecodeError:
            pass
        seed += 1

encoded = b"r\x10~\xd8\xfd\xcc\xa3\x9bm\xba\"\xfd\xcc\ry\xcc\x17\xdb\x86D\xc0\x96\x97V\xf0\xe1\xb8\x1e\xa1\xa5w|"
for seed, decoded in shifrator_bruteforce(encoded):
    print(seed, repr(decoded))

Ok я это исправил и теперь на вход шифратора подаётся чистая строка с паролем

Сделал тебе не ломаемый! Не благодари!

import random
import operator
from binascii import hexlify


def shifrator(text):
    mask = random.randbytes(len(text))
    return bytes([operator.xor(ord(s), mask[i])
                  for (i, s) in enumerate(text)]), mask


def deshifrator(ct, mask):
    return "".join([chr(operator.xor(s, mask[i]))
                    for (i, s) in enumerate(ct)])


text = "Hello world"
print(f'text: {hexlify(text.encode())}')
ct, key = shifrator(text)
pt = deshifrator(ct, key)
print(f'CT: {hexlify(ct)}')
print(f'Key: {hexlify(key)}')
print(f'PT: {hexlify(pt.encode())}')
y@sweet ~/work $ python 1.py
text: b'48656c6c6f20776f726c64'
CT: b'd1b472f41906fb69d72cd0'
Key: b'99d11e9876268c06a540b4'
PT: b'48656c6c6f20776f726c64'
  1. Рекомендовал бы автору пересмотреть процедуру генерации "ключа" из строки-пароля. Судя по исходному коду, энтропия вызванная порядком букв в пароле вообще не принимается во внимание (пароли "привет" и "твиреп" дают одинаковый seed). Стоит изучить базовые принципы KDF.

  2. Т.к. seed в итоге принимает на вход int, реально размер "ключа" составляет 32 бита, что в сочитании с атакой на основе открытого текста позволяет "взломать" "шифр" без особого труда

P.S. Строка в utf-8 тут взята только для примера

Впринципе можно шифровать любые байты

Ну, лиха беда начало, главное человек думает и пытается. Если не окажется подвержен эффекту Даннинга-Крюгера, то может что-то вырасти )

Только один вопрос зачем?!

Gpg может шифровать и паролем и открытым ключом, это раз.

Второе с точки зрения безопасности - ну тут её нет.

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

Sign up to leave a comment.

Articles