I have written an assembly I don't want other people to be able to use. My assembly is signed with a strong name key file, but how do I secure the code so that only my other assemblies signed with the same key can call the members in this assembly?
Sounds to me like an impossible problem. You can't trust your environment. That's a fundamental computing principle, and the reason for public/private key encryption.
You need to add StrongNameIdentityPermissionAttributeattributes to demand security
eg
[assembly:StrongNameIdentityPermissionAttribute(SecurityAction.RequestMinimum, PublicKey="00240000048000009400000006020000002400005253413100040000010001005" + "38a4a19382e9429cf516dcf1399facdccca092a06442efaf9ecaca33457be26ee0073c6bde5" + "1fe0873666a62459581669b510ae1e84bef6bcb1aff7957237279d8b7e0e25b71ad39df3684" + "5b7db60382c8eb73f289823578d33c09e48d0d2f90ed4541e1438008142ef714bfe604c41a4" + "957a4f6e6ab36b9715ec57625904c6")]
see this msdn page for more info
or do it in code see this example
I would suggest that you use the LicenseProvider attribute for securing use to your assembly. More information on the exact usage is available here on MSDN
Not sure if this is the best option, but you could make all the "public" classes in your assembly internal, and then use the [InternalsVisibleTo] assembly level attribute to explicitly specify your other signed assemblies.
[assembly: InternalsVisibleTo('MyAssembly,Version=1.0.0.1, Culture=neutral,PublicKeyToken=...");
Here are the MSDN docs on the attribute.
At first I thought you could make your members/classes in your signed assembly private and apply the assembly-level InternalsVisibleTo attribute to your other assemblies. I'm guessing that reflection will let you crack through that though.
Maybe the StrongNameIdentityPermission is what you are looking for.
There are a few options, none very effective as they merely will make things a tiny bit difficult, but would not prevent a committed user to work around any restriction:
On every one of your entry points, you can call Assembly.GetCallingAssembly() and compare the result with a list of assemblies that are allowed to call into your library, and throw an exception otherwise.
You could use a tool like ilmerge to merge your assemblies into your main application, and flag all of the internals as private. Combine with an obfuscator to make the results slightly better protected.
But securing an assembly is as solid as securing a computer where the attacker has physical access to it: there is very little that you can do to protect the contents once physical access is granted.
Hi Tom,
I am interested in knowing how you made the solution as I am facing a similar problem.
All the best,
Joe