Подтвердить что ты не робот

Как предотвратить спуфинг DLL в .NET.

У меня есть приложение .NET, которое ссылается на управляемую DLL.

Эта DLL содержит класс, скажем ScoreKeeper, который реализует метод под названием GetHighScore(). Приложение вызывает это периодически.

Есть ли способ предотвратить использование .NET-приложения для использования "несанкционированной" DLL вместо того, которое я поставляю?

4b9b3361

Ответ 1

Вы упомянули:

Эта DLL содержит класс, например ScoreKeeper, который реализует метод GetHighScore(). Приложение вызывает это периодически.

И затем:

Есть ли способ предотвратить использование .NET-приложения из "несанкционированной" DLL вместо того, который я поставляю?

Предполагая, что вы хотите запретить кому-либо заменять сборку, которую вы предоставили, своей собственной сборкой, которая имеет то же имя и тип (который находится в том же пространстве имен), вы могли бы примените сильное имя к сборке, содержащую класс ScoreKeeper, и обратитесь к своим потребителям.

Однако мы увидим, что есть проблемы, которые делают это не на 100% надежным. Сильные имена помогают защитить незнакомых пользователей от замены вашей DLL вредоносной поддельной копией. Но если пользователь участвует в spoofing (что было бы, если он пытался обмануть), то подписание кода будет не более чем ударом скорости и не обеспечит реальной защиты. Разумеется, сильные имена не обеспечивают защиту, сопоставимую, например, PunkBuster.

Использование сильного имени для проверки личности издателя сборки

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

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

Конечно, это означает, что вы должны защищать ключ (внутри и снаружи); если у кого-то есть ваш ключ, тогда они могут эффективно олицетворять вас и публиковать собрания, которым люди доверяют, чтобы быть от вас.

Затем, когда вы добавляете ссылку на свою подписанную сборку, если кто-то пытается поставить другую сборку с тем же именем сборки (а не с полным, просто имя без версии, хэш и открытый ключ) и того же типа имя, ошибка CLR заполнить при попытке загрузить тип, указывая, что он не смог его найти; тип разрешается с использованием полного имени сборки, а также пространства имен и имени типа.

Почему сильные имена не на 100% безопасны (ничего?)

1) Конфликты Хэша

Это все еще хэш, который проверяется. Хотя хэш довольно большой (160 бит для алгоритма хэша по умолчанию, SHA-1), любой хеш, который имеет конечное число значений, подвержен столкновению. Хотя крайне маловероятно, это возможно (невозможно и невероятно). Кроме того, по умолчанию используются только последние 8 байтов. В сочетании с исследованиями, свидетельствующими о том, что SHA-1 является относительно слабым, это хорошая причина использовать SHA-256 Enhanced Strong Naming, как описано в MSDN.

2) Удаление сильного имени

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

3) Физический доступ к сборкам означает все сборки

Если кто-то имеет доступ к физической машине и может изменить сборку, на которую вы ссылаетесь, ваша сборка также уязвима. Если злоумышленник имеет возможность изменить сильное имя сборки, на которую вы ссылаетесь, то они могут так же легко изменить вашу сборку и все остальные, участвующие в выполнении. С этой целью единственный способ быть на 100% уверенным, что физическая сборка не взломана, - это запретить физический доступ через нее. Конечно, это вызывает множество проблем безопасности.

4) Администратор отключает проверку сильного имени

Администратор компьютера может просто обойти проверку сильного имени, используя sn -Vr. Согласно MSDN:

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

5) Проверка сильного имени должна быть явно включена post.NET 3.5 SP 1

От .NET 3.5 SP 1 on, просто с сильным именем не обеспечивается защита:

Начиная с .NET Framework версии 3.5 с пакетом обновления 1 (SP1), подписи с сильным именем не проверяются, когда сборка загружается в объект AppDomain с полным доверием, например, по умолчанию AppDomain для зоны MyComputer.

Чтобы проверить .NET на сильное имя каждой сборки, загруженной в ваше приложение, вы захотите вставить следующий файл-фрагмент (предоставленный MSDN) в файл конфигурации приложения:

<configuration>
  <runtime>
     <bypassTrustedAppStrongNames enabled="false" />
  </runtime>
</configuration>

Остерегайтесь, однако, что это защищено только от удаления сильного имени.

Когда вы переопределяете функцию обхода, сильное имя проверяется только на правильность; он не проверяется на StrongNameIdentityPermission. Если вы хотите подтвердить конкретное сильное имя, вы должны выполнить эту проверку отдельно.


Если в свете вышеприведенных соображений, вы все равно хотите продолжить Strong Naming your assembly, вот как.

Создание сильного имени и подписание сборки

У вас есть два варианта использования ключа при создании сильного имени. В Visual Studio перейдите на вкладку "Подписание" в свойствах проекта и нажмите "Подписать сборку":

"Sign the assembly" option on the "Signing" tab of the project properties in VS.NET

Оттуда у вас есть две возможности генерировать открытый/закрытый ключ, чтобы VS.NET генерировал вам ключи или указывал на существующий:

"New" or "Browse" options for choosing a strong name key file

При выборе "Создать" Visual Studio предложит вам указать имя создаваемого файла, а также указать, хотите ли вы использовать пароль для доступа к нему:

Create strong name key dialog

В этот момент ключ будет добавлен в ваш проект:

Key added to project

Теперь вы можете перенести это на элемент решения (если в вашем решении есть несколько проектов).

Visual Studio в этом случае действительно просто вызывает инструмент командной строки Strong Name для создания пары открытого и закрытого ключей. Если вы предпочтете сделать это самостоятельно, вы хотите вызвать sn.exe с помощью командной строки -k для генерации ключа, например:

sn -k keyPair.snk

Затем добавьте его в диалоговом окне "Обзор".

Обратите внимание, что когда вы это сделаете, он потянет ключ в ваш проект. Если вы не хотите этого делать (поскольку он копирует ключ в каждый проект), затем удалите ключ из проекта, а затем добавьте существующий файл в проект, но свяжите его. Это очистит параметр "Выбрать сильный ключевой файл", но если вы его снимете, вы увидите полный путь к связанному ключевому файлу.

Ответ 2

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