Защитите блоки C# от лишенных полномочий Вызывающих сторон

Там какой-либо путь состоит в том, чтобы защитить Ваш блок вниз к классу/свойству и уровню класса/метода для предотвращения использования/вызова их от другого блока, который не подписывается нашей компанией?

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

Например:

Сценарий один

Foo.dll подписывается моей компанией, и Bar.dll не подписывается вообще.

Нечто имеет Панель Класса A, имеет Класс B

Класс A имеет открытый метод GetSomething (), Класс B пытается позвонить Foo. A.GetSomething () и отклоняется

Отклоненный может быть исключение или проигнорированный в некоторым образом

Сценарий два

Foo.dll подписывается моей компанией, и Moo.dll также подписывается моей компанией.

Нечто имеет Мычание Класса A, имеет Класс C

Класс A имеет открытый метод GetSomething (), Класс C пытается позвонить Foo. A.GetSomething () и не отклоняется

18
задан starblue 11 May 2010 в 13:59
поделиться

6 ответов

Если вы хотите ограничить вызывающих только кодом, который был аутентично подписан определенным сертификатом, вы все равно можете использовать CAS (только не StrongNameIdentityPermission).

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

6
ответ дан 30 November 2019 в 09:06
поделиться

Я не думаю, что есть способ сделать это, если вы не контролируете среду выполнения, в которой выполняется код. Код, работающий с полным доверием на машине пользователя, сможет обойти любые добавленные вами ограничения. Например, код полного доверия может вызывать частные или внутренние методы с помощью API-интерфейсов отражения, поэтому даже использование InternalsVisibleToAttribute не будет работать.

Если вы управляете средой выполнения, вы можете создать домен приложения, в котором ваш код полностью доверяет, а сторонний код является частично доверенным и не может вызывать ваш код, если вы не укажете AllowParhibitedTrustedCallersAttribute (APTCA) по сборке. Вы можете ограничить, какие методы могут вызываться в сборке APTCA, с помощью атрибутов SecurityCritical и SecuritySafeCritical .

Как: запустить частично надежный код в песочнице

0
ответ дан 30 November 2019 в 09:06
поделиться

Я видел библиотеки DLL, написанные компаниями (в первую очередь Pegasus Imaging ), которые используют систему запроса / ответа для разблокировки сборки. Покупателю DLL предоставляется «Лицензионный код», связанный с именем покупателя, который затем использует потребитель DLL для разблокировки определенного подмножества функций DLL.

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

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

Конечно, поскольку вы должны предоставить «закрытый ключ» в сборке, эта процедура не защищена от взлома (что такое?), Но она достаточно безопасна и сохранит честность честных людей.

2
ответ дан 30 November 2019 в 09:06
поделиться

Я думаю, это слишком много суеты зря! Если вам действительно нужна безопасность, поместите свой код за сервером и используйте архитектуру клиент-сервер. Или веб-сервисы. Или что-то среднее, например WCF или удаленное взаимодействие. Затем используйте аутентификацию для аутентификации клиента.

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

Защита dll от неавторизованных вызовов в среде только рабочего стола только усложняет задачу и затрудняет работу. Не говоря уже о том, что внутри он выглядел бы довольно некрасиво.

Я вижу, что появляются некоторые соглашения. И это может сработать для вас. Но это не дает вам «полной безопасности», которая вам нужна. Если у вас есть сборка, которая должна быть скрыта от клиентов, не помещайте ее в GAC. Используйте пространства имен с пометкой типа "ВНУТРЕННИЙ".

2
ответ дан 30 November 2019 в 09:06
поделиться

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

Изнутри метода вы можете использовать

new StackTrace().GetFrame(1).GetMethod().Module.Assembly

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

callingAssembly.GetName().GetPublicKey()

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

Но есть одна лазейка - сторонняя сборка может быть отложена с использованием открытого ключа вашей компании и исключена из проверки цифровой подписи. В результате загрузчик загрузит стороннюю сборку со строгим именем и открытым ключом вашей компании, даже если она еще не подписана. Чтобы закрыть эту дырочку, необходимо проверить подпись. Управляемого API нет, и вам нужно выполнить P / Invoke

Boolean StrongNameSignatureVerificationEx(
   String wszFilePath,
   Boolean fForceVerification,
   ref Boolean  pfWasVerified)

с fForceVerification , установленным на true , и проверить, будет ли результат true .

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

6
ответ дан 30 November 2019 в 09:06
поделиться

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

Теперь, когда это вышло из строя. Таким образом, вам придется разработать реализацию запроса-ответа самостоятельно - это не то, что вы можете сделать, если не хотите использовать подход InternalsVisibleTo , который вы явно описываете, вы не хотите use.

В модели CR вам нужно будет передавать какой-то токен при каждом вызове метода (или, возможно, просто для создания экземпляра объекта).Токеном будет класс, экземпляр которого может создать только ваш код - я бы сделал его внутренним классом сборки, которую вы хотите использовать, и сделал бы его доступным с помощью InternalsVisibleTo - таким образом, нужен только один класс для управления:

// SharedAssembly.dll
// marks ConsumingAssembly.dll as having access to internals...

internal sealed class AccessToken { }

public class SecuredClass
{
   public static bool WorkMethod( AccessToken token, string otherParameter )
   {
       if( token == null )
           throw new ArgumentException(); // you may want a custom exception.

       // do your business logic...
       return true;        
   }
}



// ConsumingAssembly.dll  (has access via InternalsVisibleTo)

public class MainClass
{
  public static void Main()
  {
      var token = new AccessToken(); // can create this because of IVT access
      SecuredClass.WorkMethod( token, "" );  // tada...
  }
}

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

Создание механизма C-R для каждого метода громоздко и утомительно. Это также не на 100% надежно - кто-то, у кого есть достаточно времени и терпения, вероятно, сможет найти способ обойти это.

Лучшим вариантом (который может быть или невозможен в вашем случае) было бы хранить ваш частный код на своих серверах и предоставлять его только как веб-сервис (или что-то подобное). Это позволяет вам активно управлять доступом к вашему IP-адресу и позволяет централизованно (а не распределенно) обновлять список пользователей, имеющих доступ. Уже существуют технологии для ограничения доступа к веб-службам с помощью сертификатов, подписи сообщений и шифрования. Это был бы самый надежный (и проверенный) способ контроля доступа к вашему IP.

2
ответ дан 30 November 2019 в 09:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: