Comments 17
Не раскрыта тема цифровой подписи. Агент генерирует пару ключей и отсылает в центр открытый ключ. Как центр может быть уверен что ключ пришел от агента, а не от имперской контрразведки? Во втором случае центр сам вручит контрразведчикам канал для передачи дезинформации.
Технически электронная подпись и асимметричное шифрование одно и то же. Электронная подпись, собственно, это закодированный закрытым ключом хеш сообщения. Но применение электронной подписи отличается от применения шифрования. Думаю, что эта тема заслуживает отдельной статьи.
Второй момент: зачем такая сложная система по доставке агенту симметричного ключа? Что мешает агенту самому сгенерировать ключ, зашифровать большой объем данных этим ключом и передать центру два сообщения: в первом примененный симметричный ключ, зашифрованный открытым ключом центра, во втором — собственно зашифрованный этим ключом массив данных.
В таком случае центр сможет убедиться, что сообщение действительно пришло от именно того агента, от которого оно ожидалось. Для этого достаточно один раз убедиться в том, что настоящий агент владеет приватным ключом, соответствующим публичному, переданному в штаб. В вашей схеме передаваемые сообщения может создавать кто угодно и у штаба нет возможности проверить, кем они отправлены и не являются ли дезинформацией.
В оригинальной схеме штаб получает от агента открытый ключ. При этом нет никакой гарантии, что в роли агента не выступает имперский контрразведчик т.к. никакой цифровой подписи не упоминается. Если же у всех агентов есть заранее сгенерированная уникальная пара ключей (как следует из вашего предложения), то да — появляется возможность идентификации агента по приватному ключу, в частности через цифровую подпись.
Честно говоря не захотелось вчитываться в код, думаю его нужно дробить на более мелкие функции с осмысленными названиями.
ну не сказать что всё плохо, но надо учитывать формат публикации — по мне так посты позразумевают именно чтение кода, с минимум усилий, а когда видишь что-то типа
iv = Random.new().read(AES.block_size)
cipher = AES.new(key_MD5, AES.MODE_CFB, iv)

сразу думаешь что все такие штуки замусоривают основной код и их надо вынести во всякие init/get_chiper
или тут
dsize = SHA256.digest_size*2
..
decrypted_message = decrypted_message_with_hesh[:-dsize

происходит авторская или криптографическая магия, которую без погружения не поймёшь, зачем и к чему этот dsize, вероятно надо структуру данных тоже пересмотреть, ну и слово hash написано неправильно.
Выкиньте из кода комментарии, их наличие означает что код плохо написан и попробуйте сделать такой, чтобы комментарии оказались не нужны, чтобы всё читалось по английски:
инициализируем шифровщик
шифруем сообщение
расшифровываем
проверяем эквивалентность

Плюс строки кажутся слишком длинными, это тоже ухудшает читаемость. Если что я просто старый ворчун и зануда.
Решение
Агент сгенерирует пару ключей (открытый и закрытый) на месте, затем отправит открытый ключ повстанческим силам;
В штабе сопротивления создадут новый ключ для СИММЕТРИЧНОГО шифрования;
Симметричный ключ закодируют при помощи открытого ключа, который прислал агент;
Зашифрованный симметричный ключ отправят агенту, который раскодирует его с помощью закрытого ключа.

И чтобы решение было идеальным, повстанцы готовят шифрованные/кодированные сообщения на отдельном рабочем месте неподключенном к сети и таким же способом расшифровывают/декодируют сообщения. Перенос информации от рабочего места, подключенного к сети на автономное рабочее место осуществляется посредством, например, флэшки.

В исправлении нет ни слова об автономном рабочем месте! А если враг получит доступ по сети к точке шифрования или дешифрования (а именно от этого защищает автономное рабочее место), то он получит и доступ к информациии и восстание будет провалено!

Безусловно шифрование сложная тема. Я старался сконцентрироваться на общих принципах и описать их как можно проще. Уверен, что специалист найдёт в таком плане кучу ошибок.

Зануда_моде_ON

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

Т.е. можно просто

cipher = AES.new(key_MD5, AES.MODE_CFB, bytes(16))
decrypted_message_with_hesh = cipher.decrypt(encr_message)[bsize:]

Но это верно только в том случае если в не планируете chiper использовать потом для шифрования.

При расшифровке сообщения мы видим, что хеш расшифрованного сообщения совпадает с хешем, который мы добавляли при шифровании. Это значит, что дешифрация прошла корректно.

Нет, нет и еще раз нет. Это значит в первую очередь то что сообщение не было изменено при передаче.

Зануда_моде_OFF

Спасибо за комментарий.
Про IV вектор написано в документации, что при применении алгоритма Cypher FeedBack его необходимо прикреплять к сообщению: "An Initialization Vector (IV) is required." (https://www.dlitz.net/software/pycrypto/api/current/Crypto.Cipher.blockalgo-module.html#MODE_CFB).


За замечания про хеш спасибо, исправлю

Это при создании сообщения (т.е. при шифровании), а при расшифровывании там уже есть IV в полученном сообщении, и для расшифровки IV не нужно инициализировать при создании chiper.
Only those users with full accounts are able to leave comments. Log in, please.