Comments 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))
Чукча не читатель, чукча писатель?
Это знакомо https://ru.wikipedia.org/wiki/Перестановочный_шифр ?
А то что вы назвали "маской" во всём мире называется перестановкой https://ru.wikipedia.org/wiki/Перестановка
Сделал тебе не ломаемый! Не благодари!
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'
Рекомендовал бы автору пересмотреть процедуру генерации "ключа" из строки-пароля. Судя по исходному коду, энтропия вызванная порядком букв в пароле вообще не принимается во внимание (пароли "привет" и "твиреп" дают одинаковый seed). Стоит изучить базовые принципы KDF.
Т.к. seed в итоге принимает на вход int, реально размер "ключа" составляет 32 бита, что в сочитании с атакой на основе открытого текста позволяет "взломать" "шифр" без особого труда
P.S. Строка в utf-8 тут взята только для примера
Впринципе можно шифровать любые байты
Ну, лиха беда начало, главное человек думает и пытается. Если не окажется подвержен эффекту Даннинга-Крюгера, то может что-то вырасти )
Только один вопрос зачем?!
Gpg может шифровать и паролем и открытым ключом, это раз.
Второе с точки зрения безопасности - ну тут её нет.
Третье, если нужно шифровать файлы то тут проще если все очень конфиденциально то только fde и криптоконтейнеры, если же нет дешевле (в ресурсах) использовать не полное шифрование файлов (так шифровальщики делают). Мог бы больше рассказать с примерами с работы, но это затянется на целую статью.
Мой алгоритм шифрования «маской» на Python