Поделиться через


Общие сведения об исходном коде (пример CNG)

В этих общих сведениях приведено высокоуровневое описание взаимодействия различных фрагментов кода в примере безопасного обмена данными с шифрованием CNG.

В разделе описаны следующие элементы примера.

  • Приложения

  • Файлы

  • Классы

  • Версии системы безопасности

  • Общие сведения о сеансах

  • Ключи шифрования (версии 2–5)

  • Обмен цифровыми подписями по открытому каналу (версия 3)

  • Обмен цифровыми подписями по закрытому каналу (версия 4)

  • Завершение сеанса (версия 5)

  • Дополнительные примечания

  • Ограничения примера CNG

Приложения

Пример состоит из трех отдельных консольных приложений: Alice, Bob и Mallory.Каждое приложение реализовано в виде отдельного проекта Visual Studio и состоит из главного файла и трех общих файлов.В следующей таблице перечислены приложения и относящиеся к ним файлы.

Имя приложения (проекта)

Файлы

Alice

  • Alice.cs (главный файл)

  • Utilities.cs

  • ChannelManager.cs

  • Communicator.cs

Bob

  • Bob.cs (главный файл)

  • Utilities.cs

  • ChannelManager.cs

  • Communicator.cs

Mallory

  • Mallory.cs (главный файл)

  • Utilities.cs

  • ChannelManager.cs

  • Communicator.cs

Файлы

В таблицах этого подраздела описаны классы и методы, которые используются каждым приложением, в порядке, определенном в исходном коде.

Alice.cs, Bob.cs и Mallory.cs

Класс, метод или

имя глобальной переменной

Использование

CNG_SecureCommunicationExample

Разделяемый класс уровня всего проекта.

MyColor

OtherColor

fDisplaySendMessage

Глобальные переменные.

Main

Точка входа в программу для каждого из приложений.Этот метод выполняет следующие операции.

  • При вызове Алисой автоматически загружает программы Bob.exe и Mallory.exe.

  • Создает цикл обработки.

  • Вызывает метод InitConsole для задания размера, положения и заголовка окна консоли.

  • Вызывает метод Run.

Run

Метод, вызывающий метод InitializeOptions и создающий выбранный сценарий безопасности.

Utilities.cs

Класс, метод или

имя глобальной переменной

Использование

CNG_SecureCommunicationExample

Разделяемый класс уровня всего проекта.

Version

fVerbose

fMallory

Глобальные переменные.

Autoloader

Метод, который Алиса вызывает, чтобы загрузить приложения Bob.exe и Mallory.exe.

InitConsole

Метод, который отвечает за меню пользовательского интерфейса и сообщения уровня приложения.

SplashScreen

Метод, который создает заголовки окон консоли.

ReadALine

Служебный метод для чтения строки, которую пользователь вводит с консоли.

ReadAChar

Служебный метод для вывода на экран вопроса и приглашения ответить "Да" или "Нет".

InitializeOptions

Метод для отображения параметров и приглашения пользователю выбрать нужные значения.Этот метод также отвечает за установку глобальных флагов Version, fVerbose и fMallory.

Display(string s)

Первый из двух методов Display.Этот метод передает строку и переменную MyColor второму методу Display.

Display(string DisplayString, int color)

Второй из двух методов Display.Этот метод создает программу-оболочку для операторов Console.WriteLine и обеспечивает поддержку цвета выводимых строк.

Дополнительные сведения об этих классах, методах и переменных см. в разделе Анализ кода классов Utility (пример CNG).

ChannelManager.cs

Класс, метод или

имя глобальной переменной

Описание

CNG_SecureCommunicationExample

Разделяемый класс уровня всего проекта.

AppControl

Метод, отвечающий за управление внутренним приложением и синхронизацию трех консольных приложений.

Алиса использует этот метод для отправки параметров программы (флагов Version и fVerbose) Бобу и Мэллори.

Метод AppControl не служит для обмена сообщениями.Его содержимое не шифруется и не подписывается.Он не вызывает класс Communicator.

SendChannelName

ReceiveChannelName

Методы, которые служат для переключения с именованного канала PublicChannel на именованные каналы AliceAndBobChannel и AliceAndBobChannel1.Именно благодаря этим методам в системе безопасности существует уязвимость, описанная в разделе Общие сведения о примере CNG.

ChannelManager

Класс, отвечающий за создание среды межпроцессного взаимодействия для приложения.

Дополнительные сведения об этих классах и методах см. в разделе Анализ кода класса ChannelManager (пример CNG).

Communicator.cs

Класс, метод или

имя глобальной переменной

Описание

CNG_SecureCommunicationExample

Разделяемый класс уровня всего проекта.

Communicator

Класс, инкапсулирующий все функции шифрования.Этот класс отвечает за обработку всех сообщений между Алисой, Бобом и Мэллори.Он не обрабатывает сообщения, отправляемые с помощью метода AppControl класса ChannelManager.

m_DSKey

m_ECDH_Cng

m_ECDH_local_publicKey_XML

m_ECDH_remote_publicKey

ChMgr

Переменные класса.

Communicator

Метод, создающий объект Communicator.

Dispose

Метод, высвобождающий занятые объектом ресурсы.

StoreDSKey

Метод для хранения ключа цифровой подписи.

Send_or_Receive_PublicCryptoKey

Метод, обеспечивающий поддержку обмена ключами.

iv

ciphertext

signature

Закрытые переменные класса, которые служат для шифрования сообщений с открытым текстом.Объявления этих переменных расположены рядом с методом ReceiveMessage().

ReceiveMessage

Метод, получающий сообщения с открытым текстом или зашифрованные сообщения в зависимости от версии системы безопасности.

SendMessage

Метод, принимающий сообщение с открытым текстом и отправляющий его в формате открытого текста или в зашифрованном виде в зависимости от версии системы безопасности.

Дополнительные сведения об этих классах, методах и переменных см. в разделе Анализ кода класса Communicator (пример CNG).

Классы

Каждый проект содержит три класса.

  • public partial class CNG_SecureCommunicationExample

    Действие этого класса распространяется на все четыре проекта, входящих в приложения Алисы, Боба и Мэллори.После компиляции класс CNG_SecureCommunicationExample будет содержать все классы, переменные и методы файлов четырех проектов.Дополнительные сведения о разделяемых классах см. в разделе Разделяемые классы и методы (Руководство по программированию в C#).

  • internal sealed class ChannelManager

    Этот класс обеспечивает работу именованных каналов.В каждом из проектов на различных этапах выполнения программы создается несколько экземпляров класса ChannelManager.Описание этого класса см. в разделе Анализ кода класса ChannelManager (пример CNG).

  • internal sealed class Communicator

    Этот класс отвечает за функции шифрования и расшифровки.В каждом из проектов на различных этапах выполнения программы создается несколько экземпляров класса Communicator.Описание этого класса см. в разделе Анализ кода класса Communicator (пример CNG).

Версии системы безопасности

Исходный код поддерживает сценарий безопасности, описанный в разделе Общие сведения о примере CNG.В нем реализованы следующие пять версий, соответствующие пяти уровням безопасности средства обмена мгновенными сообщениями.

  • Версия 1. Использование сообщений с открытым текстом и именованных каналов.

  • Версия 2. Использование зашифрованных сообщений.

  • Версия 3. Использование зашифрованных сообщений и цифровых подписей.

  • Версия 4. Использование зашифрованных сообщений и закрытой цифровой подписи.

  • Версия 5. Завершение работы приложения при возникновении ошибок безопасности.

Примечание

Далее в этом разделе при упоминании различных версий указываются их номера.Кроме того, в зависимости от контекста имена Алиса (Alice), Боб (Bob) и Мэллори (Mallory) могут относиться к трем действующим лицам описываемого сценария или к трем приложениям Visual Studio.

Общие сведения о сеансах

В каждом из приложений Алисы, Боба и Мэллори имеются методы Main и Run.

Метод Main синхронизирует приложения и выполняет следующие функции.

  • Отображение экрана-заставки при запуске.

  • Вывод запроса пользователя с предложением выбрать параметры сеанса (только у Алисы).

  • Отправка параметров сеанса приложениям Боба и Мэллори (только у Алисы).

  • Получение параметров сеанса от Алисы (только у Боба и Мэллори).

  • Вызов метода Run для запуска запрашиваемого сеанса безопасности.

Метод Run выполняет сценарии безопасности.

  • Каждый сеанс соответствует одной из перечисленных в предыдущем подразделе версий.

  • Сеанс начинается, когда приложения Алисы, Боба и Мэллори запускают свои методы Run, и завершается, когда управление возвращается методам Main.

  • Во время сеанса приложения Алисы, Боба и Мэллори всегда выполняют одну и ту же версию сценария.

  • Алиса инициирует все происходящие во время сеанса транзакции.Мэллори отвечает Алисе и инициирует транзакции для Боба.Боб только отвечает.

Исходный код приложений Алисы и Боба очень похож.Основное различие состоит в том, что Алиса инициирует все сеансы и выступает в роли сервера канала, а Боб всегда выступает в роли клиента канала.Код Мэллори более сложный, поскольку он управляет двумя отдельными каналам: первый связывает его с Алисой, второй — с Бобом.

Метод Main

Приложение Алисы вызывает метод InitializeOptions в начале метода Main и получает у пользователя параметры сеанса (Version, fVerbose, fMallory).Затем с помощью метода AppControl эти параметры передаются Бобу и Мэллори, которые принимают их с помощью своих методов AppControl.Если пользователь принимает решение закрыть приложение, введя букву "x", вместо параметров сеанса метод AppControl Алисы отправляет Бобу и Мэллори строку "exit".

По получении параметров сеанса всеми тремя приложениями вызываются методы Run.

Метод Run

Чтобы запустить запрашиваемый сеанс, Алиса, Боб и Мэллори выполняют следующие действия.

  1. Алиса вызывает метод SendChannelName, который использует канал с именем PublicChannel.Она отправляет Бобу имя нового канала (AliceAndBobChannel).

  2. Если флаг fMallory имеет значение true, Мэллори прослушивает канал PublicChannel и перехватывает имя нового канала (AliceAndBobChannel), передаваемое Алисой.Затем он отправляет Бобу другое имя канала (AliceAndBobChannel1).

  3. Алиса и Боб создают объекты Communicator, названные их именами.Эти объекты создаются внутри операторов using C# и удаляются по окончании работы метода Run.

    Алиса инициализируется в качестве сервера канала:

    using (Communicator Alice = new Communicator("server", NewChannelName))
    

    Боб инициализируется в качестве клиента канала:

    using (Communicator Bob = new Communicator("client", NewChannelName))
    

    Мэллори создает два объекта Communicator: MalloryAlice и MalloryBob.Мэллори инициализируется в качестве клиента канала для Алисы:

    using (Communicator MalloryAlice = new Communicator("client", AliceChannelName))
    

    Мэллори инициализируется в качестве сервера канала для Боба:

    using (Communicator MalloryBob = new Communicator("server", BobChannelName"))
    
  4. Конструктор класса Communicator принимает имя канала и создает долгосрочный открытый объект ChannelManager с именем ChMgr:

    ChMgr = new ChannelManager(mode, ChannelName);
    
  5. Конструктор ChannelManager принимает имя канала и создает соответствующий именованный канал.

    Примечание

    На этом этапе Алиса и Мэллори взаимодействуют по каналу с именем AliceAndBobChannel, а Мэллори и Боб — по каналу с именем AliceAndBobChannel1.

    AliceAndBobChannel и AliceAndBobChannel1 — это долгосрочные каналы, которые остаются открытыми до завершения сценария безопасности (т. е. до завершения метода Run).

  6. Значения флага fVersion (который обозначает версию системы безопасности) и флага fMallory (который отвечает за участие Мэллори) определяют дальнейшее развитие событий.

    В версии 3 Алиса по каналу PublicChannel отправляет Бобу ключ цифровой подписи.Они используют этот ключ цифровой подписи, чтобы подписывать ключи и сообщения.Если флаг fMallory имеет значение true, Мэллори перехватывает ключ цифровой подписи и использует его для подписывания ключей и сообщений, которые он отправляет Алисе и Бобу.

    В версиях 4 и 5 Алиса отправляет Бобу два ключа цифровой подписи.Ключ цифровой подписи 1 — это тот же ключ, который Алиса отправляла в версии 3.Ключ цифровой подписи 2 — это секретный ключ цифровой подписи, о котором Мэллори не знает.

  7. В версиях 2–5 Алиса и Боб обмениваются открытыми ключами шифрования.Если флаг fMallory имеет значение true, Мэллори перехватывает их открытые ключи и заменяет их своими ключами.

  8. Алиса и Боб обмениваются сообщениями. Если флаг fMallory имеет значение true, Мэллори перехватывает, подменяет и заново отправляет сообщения Алисы и Боба.

  9. Когда Алиса и Боб завершат обмен сообщениями, пользователь получит приглашение отправить собственное сообщение.Это позволит ему понять, как происходит шифрование сообщений и что делает Мэллори для их изменения.После этого нажмите клавишу ВВОД, чтобы вернуть управление Алисе.

  10. Алиса завершает сеанс.Методы Run Алисы, Боба и Мэллори возвращают управление своим методам Main, и пример перезапускается.

Ключи шифрования (версии 2–5)

В версиях 2–5 сообщения шифруются с помощью алгоритма AES.Обмен ключами шифрования реализован в методах Run Алисы, Боба и Мэллори после следующего оператора:

if (2 <= Version)

Ключ шифрования отправляется долгосрочным открытым объектом ChannelManager (ChMgr), который создается конструктором класса Communicator.

В следующих двух операторах показано, как Алиса отправляет, а Боб принимает ключ шифрования:

Alice.Send_or_Receive_PublicCryptoKey("send", MyColor);
Bob.Send_or_Receive_PublicCryptoKey("receive", OtherColor);

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

Считается, что реализации AES невозможно взломать математически.Однако они не обеспечивают защиты от атаки "злоумышленник в середине".Может показаться странным, что Мэллори может расшифровать сообщения Алисы и Боба, хотя алгоритм AES и обеспечивает такое надежное шифрование.Это становится возможным, потому что у Мэллори имеется общее секретное соглашение Алисы и Боба.Тот факт, что Мэллори может перехватывать и подменять сообщения, делает шифрование AES бессмысленным.

Использование ключей шифрования без проверки подлинности создает обманчивое впечатление защищенности.Алиса и Боб полагают, что при использовании версии 2 у них имеется безопасная система обмена сообщениями.Однако защита нарушается еще до того, как они отправят первое сообщение.

Компания Алисы и Боба не знает, где находится злоумышленник — внутри компании или за ее пределами.Она разрабатывает версию 3 средства обмена мгновенными сообщениями, чтобы обнаружить источник атак.

Обмен цифровыми подписями по открытому каналу (версия 3)

В версии 3 предпринимается попытка устранить уязвимость версии 2 за счет использования цифровой подписи для подписывания ключей и сообщений.Обмен ключами цифровых подписей реализован в методах Run Алисы, Боба и Мэллори после следующего оператора:

if (3 <= Version)

Ключ цифровой подписи передается по тому же долгосрочному открытому каналу, что и ключи шифрования.За передачу ключа цифровой подписи отвечает следующий код:

Alice.ChMgr.SendMessage(dsKeyBlob);

Примечание

Экземпляр ChannelManager (ChMgr), который отправляет ключ цифровой подписи, является членом объекта Communicator Алисы.

Алиса и Боб хранят ключ цифровой подписи в форме закрытого члена своих объектов Communicator:

Alice.StoreDSKey(DSKey);
Bob.StoreDSKey(DSKey);

К сожалению, Мэллори может легко скопировать цифровую подпись из канала PublicChannel и сохранить ее:

Mallory.StoreDSKey(DSKey);

Когда Алиса и Боб получают друг от друга подписанные сообщения, цифровые подписи в точности соответствуют сообщениям.Это связано с тем, что Мэллори подписывает их с помощью того же ключа цифровой подписи, что и Алиса с Бобом.

В версии 3 ключи шифрования и цифровая подпись передаются по открытому каналу в сети компании.Компания, в которой работают Алиса и Боб, подозревает, что злоумышленник находится внутри компании.Компания создает версию 4, чтобы проверить эту теорию.

Обмен цифровыми подписями по закрытому каналу (версия 4)

В версии 4 используется два ключа цифровой подписи: ключ, который использовался в версии 3, и второй, секретный ключ, который передается по закрытому каналу.Теперь первый ключ является поддельным цифровым ключом, который нужен, чтобы выследить вора.Второй ключ Алиса и Боб используют, чтобы подписывать свои ключи шифрования и сообщения.

Только Алиса и Боб имеют версию 4 программного обеспечения для обмена мгновенными сообщениями.Мэллори продолжает использовать версию 3.Поэтому Мэллори никогда не узнает, что цифровая подпись, которую он использует, недействительна.Однако средство обмена мгновенными сообщениями Алисы и Боба выводит предупреждение безопасности всякий раз при получении ключа или сообщения.

Версия 4 также демонстрирует, что перехватываются как ключи шифрования, так и сообщения.Это говорит о том, что имеет место атака "злоумышленник в середине" и что она началась еще до отправки ключа шифрования.Поэтому сотрудник компании, у которого есть доступ к каналу PublicChannel, должен входить в сеть до Боба.Правильное использование секретного ключа цифровой подписи позволяет выявить тайную деятельность Мэллори.

Передача секретного ключа цифровой подписи реализована в методах Run Алисы, Боба и Мэллори после следующего оператора:

if (4 <= Version)

Следующие операторы кода отвечают за создание закрытых экземпляров ChannelManager Алисы и Боба:

ChannelManager ChMgr2 = new ChannelManager("server", "PrivateChannel")
ChannelManager ChMgr2 = new ChannelManager("client", "PrivateChannel")

Закрытый канал, который используют Алиса и Боб (ChMgr2), не является членом их объектов Communicator.Это можно понять, сравнив следующие операторы:

Alice.ChMgr.SendMessage(dsKeyBlob); // Public channel - fake key
ChMgr2.SendMessage(dsKeyBlob);      // Private channel - real key

В первом операторе используется долгосрочный экземпляр ChannelManager (ChMgr), который создается при запуске метода Run.Этот экземпляр хранится в виде открытого члена объектов Communicator Алисы, Боба и Мэллори (см. шаг 3 в разделе Общие сведения о сеансах) до конца сеанса.Во втором операторе используется временный объект, который существует только на время отправки и получения ключа.Этот объект удаляется сразу после использования.

После отправки секретного ключа цифровой подписи Алисой Боб получает его с помощью следующего оператора:

DSKey = ChMgr2.ReadMessage();

Алиса и Боб сохраняют ключ в виде закрытого члена своих объектов Communicator:

Alice.StoreDSKey(DSKey);
Bob.StoreDSKey(DSKey);

Кроме того, в результате выполнения этих операторов поддельный ключ цифровой подписи перезаписывается.

В версии 4 Алиса и Боб используют для подписывания ключей и сообщений секретный ключ цифровой подписи вместо поддельного ключа цифровой подписи.Кроме того, в версии 4 подписываются ключи шифрования и отображаются предупреждения безопасности, если цифровая подпись не соответствует сообщению.

Завершение сеанса (версия 5)

Версия 5 идентична версии 4, но в ней сеанс завершается при первой же ошибке.При получении от Боба открытого ключа шифрования Алиса обнаруживает недействительную цифровую подпись, и происходит первая ошибка.У Боба первая ошибка происходит, когда он получает от Алисы открытый ключ шифрования и также обнаруживает недействительную цифровую подпись.

Дополнительные примечания

  • Удаление объектов. Операторы using C# обеспечивают дополнительный уровень безопасности.В них заключаются все объекты ChannelManager и Communicator.Когда объекты оказываются за пределами области действия, сразу же вызываются их методы Dispose, и все занятые внутри этих объектов ресурсы, высвобождаются.

  • Методы кодирования. При передаче зашифрованных данных необходимо всегда использовать кодировку UTF8 или Unicode, но никогда не использовать кодировку ASCII.

Ограничения примера CNG

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

  • Проверка параметров во всех методах.

  • Активное использование блоков try/catch.

  • Надежные методы выявления отключения каналов.

  • Вывод появляющейся на экране информации в файл журнала.

  • Динамическая настройка алгоритма шифрования.

  • Динамическая настройка алгоритма цифровой подписи.

  • Альтернативный способ передачи Бобу ключа цифровой подписи.Именованный канал PrivateChannel является простым решением, однако существует и другой, более изощренный метод.

  • Сохраняемость, хранение и извлечение ключей.

  • Использование ключей цифровой подписи, создаваемых операционной системой.

  • Использование ключей, полученных с помощью инфраструктуры открытого ключа (PKI).

Реализация этих функций потребовала бы усложнения кода и выходит за рамки данного примера.

См. также

Основные понятия

Пример защищенного обмена данными с шифрованием CNG

Пошаговое описание процесса обмена ключами и сообщениями (пример CNG)

Ожидаемый выводимый результат (пример CNG)