Alexander_tt0
@Alexander_tt0
Интеграл в уме

Как решать подобные задачи по криптографии?

Решаю олимпиаду, но не могу понять суть таких задач. Криптография в принципе не дается.
Петя начитался курсов по криптографии для начинающих, и решил, что его осенило! Теперь он написал свою функцию шифрования и расшифрования по секретному ключу. Для наглядности он предоставил исходный текст, зашифрованный исходный текст, а также зашифрованный флаг. Действительно ли его реализация идеальна? P.S. Флаг имеет формат вида ntcontest{FLAG_VALUE}
import random
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad as padding_tool


some_bytes = b""

with open("./example_plain", "rb") as f:
    some_bytes = f.read()

with open("./flag_plain", "rb") as f:
    flag_bytes = f.read()
def encrypt_me(plain_text):
    key_val = b""
    seed_val = plain_text[0]
    random.seed(seed_val)
    for i in range(16):
        key_val += random.randrange(1, 255).to_bytes()

    cipher = AES.new(key_val, AES.MODE_ECB)
    cipher_text = cipher.encrypt(padding_tool(plain_text, 16))
    print(cipher_text)
    print(key_val)
    return cipher_text, key_val
    
def decrypt_me(cipher_text, key_val):
    cipher = AES.new(key_val, AES.MODE_ECB)
    plain_text = cipher.decrypt(cipher_text)
    print(plain_text)

example_cipher_text, example_key = encrypt_me(some_bytes)
with open("./example_enc", "wb") as f:
    f.write(example_cipher_text)

decrypt_me(example_cipher_text, example_key)

flag_cipher_text, flag_key = encrypt_me(flag_bytes)
with open("./flag_enc", "wb") as f:
    f.write(flag_cipher_text)

decrypt_me(flag_cipher_text, flag_key)

Example_enc:
o|L\#ѓЏф>^зфЊ йќєч‚дWxc¦‰~С6

Example_plain:
THIS IS THE BEST CIPHER

Flag_enc:
Њ„t·:СдЦIt’q|«=О›й#qaAњ4QV9мёаO®zrб‚ЄН¶€ё
  • Вопрос задан
  • 204 просмотра
Решения вопроса 2
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
Как решать подобные задачи по криптографии?

Для начала прочитать условия и заглянуть в код. Увидеть в нём вот это:
key_val = b""
    seed_val = plain_text[0]
    random.seed(seed_val)
    for i in range(16):
        key_val += random.randrange(1, 255).to_bytes()

понять, что key_val однозначно генерируется из первого символа открытого текста.

Флаг имеет формат вида ntcontest{FLAG_VALUE}

Я не понял эту часть, имеется в виду, что первый символ открытого текста флага -- 'n'? Если так, то вообще решение в одно действие, если нет, то в любом случае можно организовать перебор всех возможных первых символов, генерировать по ним key_val, расшифровывать им и проверять, что первый символ полученного текста совпадает с символом использованным для генерации ключа.
Ответ написан
Комментировать
vesper-bot
@vesper-bot
Любитель файрволлов
Как решать - алгоритмически. Любая криптография - это набор алгоритмов преобразования данных итд, которые можно выполнить руками и посмотреть на все промежуточные данные. А также на то, из чего они порождены, как здесь, где в качестве random seed использован один байт. И если вы увидели, что какой-то элемент промежуточных данных оказывается статичным или из небольшого множества возможных значений, создаете множество и применяете перебор (в самом крайнем случае, иногда и он не нужен). "Взрослая" криптография обычно куда сложнее, но и там бывает, что какие-то величины оказываются не из полного пространства 2^N, тогда алгоритм использования этого факта называется "атака уменьшения сложности". Вот искать такое - уже нужно разбираться в высшей математике на уровне математических абстракций, а олимпиадные задачи чаще всего требуют относительно простого анализа алгоритма или кода.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы