- •Постановка задачи
- •Обзор современного состояния темы
- •Выбор алгоритмов и атак
- •Критерии выбора алгоритмов
- •Выбор симметричных алгоритмов шифрования
- •Выбор алгоритмов шифрования с открытым ключом
- •Выбор алгоритмов цифровой подписи
- •Выбор криптографических атак
- •Описание использованных криптографических алгоритмов
- •Симметричные алгоритмы шифрования
- •Алгоритм гост
- •Асимметричные алгоритмы шифрования
- •Алгоритмы цифровой подписи
- •Алгоритм гост
- •Описание использованных атак
- •Атака на общий модуль против алгоритмаRsa
- •Атака на выбранный шифртекст против алгоритмаRsa
- •Атака против алгоритмаDsa
- •Особенности реализации алгоритмов
- •Управление ключами
- •Генерация ключей
- •Хранение ключей
- •Длина ключа
- •Особенности реализации асимметричных алгоритмов
- •Модульная арифметика
- •Представление многозначных чисел
- •Сложение многозначных чисел
- •Умножение многозначных чисел
- •Деление многозначных чисел
- •Особенности реализации симметричных алгоритмов
- •Дополнение сообщений
- •Подключи и таблицы подстановки для алгоритмаBlowfish
- •Режим использования блочных шифров
- •Проектирование интерфейса
- •Сценарии использования программы
- •Пошаговое выполнение симметричных алгоритмов
- •Пошаговое выполнение асимметричных шифров
- •Пошаговое выполнение алгоритмов цифровой подписи
- •Демонстрация работы атак
- •Оценка скорости работы алгоритма
- •Структура диалога
- •Архитектура программы
- •Использование объектов-функций
- •Использование потоков
- •Использование генераторов ключей
- •Структура модулей
- •Заключение
- •Список литературы
Использование потоков
В программе существует 2 формата данных, передаваемых криптографическим алгоритмам:
Двоичный формат. Данные интерпретируются как последовательность байт.
Десятичный формат. Он используется для асимметричных алгоритмов. Данные интерпретируются как последовательность чисел, записанных в десятичной системе.
Шестнадцатеричный формат. Он используется для симметричных алгоритмов. Данные интерпретируются как последовательность чисел от 0 до 255, записанных в 16-ричной системе.
Перед обработкой данных требуется указать формат. Пусть, например, алгоритм RSAс открытым ключомn=789499 иe=3 используется для шифрования строки «239». При использовании двоичного формата эта строка сначала будет преобразована в последовательность чисел
50 51 57,
а затем по формуле c=memodnбудет преобразована в последовательность чисел
125000 132651 185193.
При использовании десятичного формата та же строка будет интерпретирована как число 239, и результатом шифрования будет число 230436. Если же передать строку «алгоритм» при использовании десятичного формата, то никаких действий произведено не будет, т.к. эта строка не является последовательностью чисел в десятичной системе.
Передача данных в виде массива символов char*, количества байт и формата обладает несколькими существенными недостатками:
Требуется следить, чтобы использованная память была освобождена.
Для передачи данных из файла требуется сначала считать данные из него в буфер. Но считывание всех данных одновременно приведет к большому расходу памяти, а считывание по частям – к чрезмерно сложному коду.
Часто возникают ошибки из-за невнимательности программиста.
Поэтому было решено использовать классы потокового ввода/вывода из стандартной библиотеки C++. В качестве параметра передается ссылка на объект классаstd::istreamилиstd::ostream. При этом все недостатки первого способа передачи данных исчезают. Разнообразие потоков приводит к тому, что можно легко шифровать или подписывать данные из файла, строки или с консоли, и выводить в любое из перечисленных мест. Например, объявление функцииEncryption::Encryptвыглядит так
voidEncrypt(std::istream&msg,std::ostream&cipher).
Возможности потоков позволяют передать и формат ввода данных. Для вновь созданного потока используется десятичный или шестнадцатеричный формат. Чтобы установить двоичный формат используется специальная функция-манипулятор Binary. Для отмены двоичного обмена используется манипуляторDecHex. Узнать, используется ли двоичный формат, можно с помощью функцииIsBinary.
Использование генераторов ключей
Реализация алгоритма генерации ключей в каждом из классов, представляющих криптографические алгоритмы, приведет к дублированию кода. Вариант, при котором каждый из классов RSAEncrypt,RSADecrypt,RSASignиRSAVerifyнаследовался бы от одного класса, в котором была бы реализована генерация ключей, также не подходит. Ведь ключи генерируются случайным образом, а такой вариант привел бы к тому, что, например, шифратор и дешифратор, имели разные ключи. Поэтому для каждого криптографического алгоритма решено создать отдельный класс – генератор ключей. Сначала создается объект этого класса, затем с его помощью генерируются ключи, а затем эти ключи передаются всем объектам-алгоритмам.
Для двухключевых алгоритмов создано 4 таких генератора – RSAKeyGenerator,ElGamalKeyGenerator,DSAKeyGenerator,GOSTKeyGenerator. В каждом из них определена функция-членGetKeys, которая возвращает пару ключей – открытый и секретный. Для одноключевых алгоритмов создан 1 генератор –BlockKeyGenerator, который возвращает случайный ключ заданной длины.