如何防止其他人使用我的.Net程序集?
我有一个程序集,除了指定的可执行文件之外,任何其他应用程序都不应使用该程序集。请给我一些指导。
解决方案
我们可能可以在程序集的"代码访问安全性"策略中进行设置。
我们应该能够使所有内容都在内部范围内,然后使用InternalsVisibleTo属性授予该程序集仅对内部方法的访问权限。
在.Net 2.0或者更高版本中,将所有内容置于内部,然后使用"朋友程序集"
http://msdn.microsoft.com/zh-CN/library/0tke9fxk.aspx
这不会停止反射。我想从下面合并一些信息。如果我们绝对需要阻止任何人打电话,最好的解决方案是:
- ILMerge .exe和.dll
- 混淆最终的.exe
我们还可以检查调用堆栈并获取每个调用方的程序集,并确保它们均使用与程序集相同的密钥签名。
例如,如果程序集是Web服务,则可以确保指定的可执行文件在SOAP消息中传递了秘密值。
我们可以使用混淆。
那将变成:
int MySecretPrimeDetectionAlgorithm(int lastPrimeNumber);
变成一些不可读的东西:
int Asdfasdfasdfasdfasdfasdfasdf(int qwerqwerqwerqwerqwerqwer);
其他人仍然可以使用程序集,但是要使任何明智的操作变得困难。
100%完全不可能不跳环而已。
使用.NET的好处之一是可以使用反射,即加载程序集并检查它,动态调用方法等。这就是VB.NET与Fpossible之间互操作的原因。
但是,由于代码位于托管程序集中,这意味着任何人都可以添加对我们代码的引用,并调用其公共方法或者使用反射和调用私有方法加载它。即使我们"混淆"了代码,人们仍然可以使用反射并调用代码。但是,由于所有名称都将被屏蔽,所以做任何事情都非常困难。
如果必须以阻止其他人执行.NET代码的方式发布.NET代码,则可以使用NGEN二进制文件(将其编译为x86)并交付这些二进制文件。
我不了解情况的具体细节,但是混淆应该足够了。
@Charles Graham提到的代码访问安全性属性是StrongNameIdentityPermissionAttribute
正如某些人提到的那样,使用InternalsVisibleTo属性并将所有内容标记为内部。当然,这不会防止反射。
尚未提及的一件事是将程序集合并到主.exe / .dll /中,无论如何,这都会增加一点输入的障碍(人们将无法坐在自己的要求引用的状态下看到组件),但不会停止反射路径。
更新:此外,IIRC,ilmerge具有可以自动内部化合并程序集的功能,这意味着我们根本不需要使用InternalsVisibleTo
我们可以使用相同的密钥对程序集和可执行文件进行签名,然后在要保护的类的构造函数中进行检查:
public class NotForAnyoneElse { public NotForAnyoneElse() { if (typeof(NotForAnyoneElse).Assembly.GetName().GetPublicKeyToken() != Assembly.GetEntryAssembly().GetName().GetPublicKeyToken()) { throw new SomeException(...); } } }
我们也可以看看使用Netz可执行打包程序和压缩程序。
这会将程序集和.exe文件打包到一个可执行文件中,因此,如果不进行深入挖掘,它们就不会对外界可见。
我的猜测是,这足以阻止大多数.net程序员访问。
.netz方法的一个很大的好处是它不需要我们更改代码。另一个好处是,它确实简化了安装过程。
听起来我们正在寻找保护或者混淆工具。虽然没有灵丹妙药,但我推荐的保护工具是smartassembly。一些替代品是Sal混淆器,点混淆器和Xenocode。
不幸的是,如果我们将字节提供给某人阅读……如果他们有足够的时间和精力,他们可以找到加载和调用代码的方法。要抢先回答评论,我经常看到我们问:Salamander将阻止代码直接加载到Reflector工具中,但是我在smartassembly方面拥有更好的体验(即:更可靠)。
希望这可以帮助。 :)
我不确定这是否对我们有用,但是也许我们可以使用WCF或者ASP.NET Web服务托管程序集,并使用某种身份验证方案(LDAP,公共/伪造密钥对等)来确保仅允许客户端连接。这将使程序集在物理上不受其他任何人的控制,并且我们可以控制连接到它的人。只是一个想法。
只需要求使用函数调用发送密码,如果未得到授权,则无济于事,如.setAuthorizeCode('123456'),然后在每个可以使用的地方检查它,是否需要authorizeCode!= 123456然后抛出错误或者退出……听起来像是对可重用性的好答案,但这就是重点。
唯一可以使用的时间是我们自己,当我们进行硬编码时,将授权代码写入程序。
只是一个想法,可能就是我们正在寻找的东西,或者可能会激发我们做些更好的事情。