Alex Rivera | Logout

Secure C# Assemblies from unauthorized Callers

Asked 2010-05-10T22:17:24.737
18

Is there any way to secure your assembly down to the class/property & class/method level to prevent the using/calling of them from another assembly that isn't signed by our company?

I would like to do this without any requirements on strong naming (like using StrongNameIdentityPermission) and stick with how an assembly is signed. I really do not want to resort to using the InternalsVisibleTo attribute as that is not maintainable in a ever changing software ecosystem.

For example:

Scenario One

Foo.dll is signed by my company and Bar.dll is not signed at all.

Foo has Class A Bar has Class B

Class A has public method GetSomething() Class B tries to call Foo.A.GetSomething() and is rejected

Rejected can be an exception or being ignored in someway

Scenario Two

Foo.dll is signed by my company and Moo.dll is also signed by my company.

Foo has Class A Moo has Class C

Class A has public method GetSomething() Class C tries to call Foo.A.GetSomething() and is not rejected

Edit
Report

2 Answers

6

If you are wanting to limit the callers to only code that has been authenticode signed by a specific certificate, you can still use CAS (just not StrongNameIdentityPermission).

Use PublisherIdentityPermission just like you would have used any CAS permissions. Or if you want to do it declaratively, use an attribute.

answered 2010-05-10T22:47:52.543
2

First of all, as you realize, it's not enough to use InternalsVisibleTo - you would also need to sign and strongly-name each assembly to ensure someone can't just spoof the name.

Now that that's out of the way, you would have to develop a challenge-response implementation on your own - this isn't something you can do unless you're willing to use the InternalsVisibleTo approach that you explicitly describe you don't want to use.

In a C-R model, you would need to pass some kind of token with every method call (or perhaps just to instantiate an object). The token would be a class that only your code can create an instance of - I would make this an internal class of the assembly you want to consume and make it accessible with InternalsVisibleTo - this way only a single class needs to be managed:

// 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...
  }
}

You may want to put the AccessToken class in a third assembly that both the service provider and consumer know about so that you don't have to constantly maintain a different group for access token classes for different assemblies.

Building a C-R mechanism for every method is cumbersome and tedious. It also isn't 100% foolproof - someone with enough time and patience could probably find a way around it.

answered 2010-05-10T22:39:32.500

Your Answer