MEF: проверка подлинности компонентов - PullRequest
4 голосов
/ 25 октября 2010

Я создаю приложение Windows (Service), которое, вкратце, состоит из «загрузчика» и «движка» (объекта, загружаемого загрузчиком, который передает ему управление, а затем выполняет реальные задачи приложение). Загрузчик - это очень простая процедура запуска, в которой мало функций, которые могут измениться. Но сам механизм может быть подвергнут обновлению после установки, и я реализую механизм, который может сам обновляться - связавшись с «главным сервером» и проверив номер его версии по «самой последней» версии. Если доступна более новая версия движка, он загрузит его в назначенную папку и вызовет метод в загрузчике для «перезагрузки».

Таким образом, всякий раз, когда запускается загрузчик, он использует MEF для «сканирования» соответствующих каталогов для реализаций IEngine, сравнивает их числа совместимости загрузчика и выбирает новейшую совместимую версию движка. Затем он передает управление движку (который, в свою очередь, выполняет проверку обновлений и т. Д.). Если нет подходящих IEngines - или MEF дает сбой во время компоновки - он использует стандартную встроенную реализацию IEngine.

Это приложение будет работать на удаленном сервере (или нескольких), и вся причина в том, чтобы свести к минимуму ручное обслуживание приложения (например, не нужно удалять / загружать новую версию / переустанавливать и т. Д.).

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

Я ищу механизм для проверки того, что реализация IEngine является «аутентичной» - как выдано соответствующим органом. Я поигрался с некоторыми домашними «решениями» (когда IEngine предоставляет функцию Validate, которая проходит «вызов» и должна возвращать правильный «Response») - различными способами, например, когда загрузчик производит случайную строку, которая зашифровывается и передается кандидату-механизму, который затем должен расшифровать и изменить строку, затем хэшировать ее, зашифровать хеш и вернуть ее загрузчику, который выполнит аналогичную модификацию строки в своей случайной строке, затем хеширует ее и сравнивает хеш до расшифрованного ответа (хеш) от кандидата и т. д.), но я уверен, что в .Net есть функции для выполнения такого рода проверки? Я только что посмотрел на Strong Naming, но, похоже, это не лучший способ для системы, которая будет динамически загружаться, пока не придумано dll ..

Вход будет высоко оценен.

Ответы [ 2 ]

6 голосов
/ 25 октября 2010

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

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

Вы можете получить открытый ключ, позвонив Assembly .GetName () .GetPublicKey () , а затем сравнить его с ожидаемым, т. Е. Вашим.

Вы можете сканировать сборки плагинов, создать AssemblyCatalogдля каждого с правильным открытым ключом (отвергая другие), наконец, объединяя их в AggregateCatalog и создавая CompositionContainer с ним.

Это в основном то, что Гленн Блок также объяснил в нить .(Лучше всего игнорировать сообщение в блоге, на которое ссылается Бная, его интерпретация StrongNameIdentityPermission неверна.)

edit с ответами на стену комментариев:

Чтобы получить этот открытый ключ, я заставляю консольное приложение выводить куда-нибудь массив байтов открытого ключа.Я встраиваю байтовый массив в мое хост-приложение и впоследствии использую его для сравнения с открытыми ключами кандидатов на плагин.Это был бы способ сделать это?

Да, но есть более простой способ извлечь открытый ключ.Посмотрите на параметр -Tp sn.exe .

. Этот механизм автоматически препятствует тому, чтобы сборка вредоносного плагина выставляла правильный, но "поддельный" открытый ключ?Например, существует ли какой-либо механизм для дисквалификации любой сборки, которая подписана, но имеет несоответствие между ее открытым открытым ключом и его внутренним закрытым ключом, от загрузки / запуска вообще?

НасколькоЯ знаю, проверка происходит автоматически.Сборка со строгим именем не может быть загружена (даже динамически), если ее подпись неверна.В противном случае сильное имя будет бесполезным.Чтобы проверить это, вы можете открыть сборку со строгим именем в шестнадцатеричном редакторе, изменить что-либо (например, символ в const string, встроенном в сборку) и убедиться, что сборка больше не может быть загружена.

Я думаю, что я имел в виду что-то похожее на тип хака / крэка, описанный здесь: http://www.dotnetmonster.com/Uwe/Forum.aspx/dotnet-security/407/Signed-assemblies-easily-cracked и здесь: http://blogs.msdn.com/b/shawnfa/archive/2008/05/14/strong-name-bypass.aspx

[... snip more comments...]

Однако это, по-видимому, можно обойти простым вмешательством (как показано в первой ссылке> и объяснено подробнее здесь): grimes.demon.co.uk/workshops/fusionWSCrackOne.htm

«Атаки», о которых вы говорите, подразделяются на три категории:

  • , полностью удаляя строгое имя.Это не нарушает аутентификацию, сборка больше не будет иметь открытого ключа, и вы ее отклоните.
  • отключение проверки строгого имени, которая требует полного доступа к машине.Если это сделал злоумышленник, это будет означать, что злоумышленник уже владеет вашей машиной.Любой механизм безопасности был бы бессмысленным в таком контексте.На самом деле мы защищаемся от атакующего между машиной и источником сборок.
  • настоящий эксплойт, ставший возможным благодаря ошибке в .NET 1.1, которая с тех пор была исправлена ​​

Вывод: строгие имена подходят для аутентификации (по крайней мере, начиная с .NET 2.0)

2 голосов
/ 02 ноября 2010

Я написал пост в блоге с исходным кодом для каталога, который загружает сборки только с указанными вами ключами: Как контролировать, кто может писать расширения для вашего приложения MEF

...