0

我有一个接口,它在我的应用程序中通过 MEF 实现类导出。实现类位于单独的程序集中,并且在编译时不知道(想想插件)。

该接口基本上由一个调用组成,该调用说“这是一堆键值对,现在初始化您的许可状态”。IE

public LicensingInfo InitialiseLicense(IEnumerable<KeyValuePair<string, string>> keys)

我想知道的是 - 有没有办法保护该接口免受“中间人”实现的影响?即,接收来自我的应用程序的调用,然后使用不同的键值对在插件程序集上调用相同的方法,基本上说“是的 - 在这里你去 - 拥有一切”。

我确实尝试过以不同的方式思考它,因为应用程序将调用插件程序集并传入一个可以查询的对象。该方法可能如下所示:

public LicensingInfo InitialiseLicense(ILicenseQueryProvider provider)

但是,再次使用这种方法,我认为拦截对象可以简单地为库提供不同的提供者。

那么,有没有办法可以防止这种接口拦截,或者我应该重构它,以便插件程序集完全负责它自己的代码中的许可证加载等?还是有另一种方法,也许,我可以重构我没有考虑过的?

4

2 回答 2

2

我相信您可以使其更难破解,但不能使用界面。

这是你要做的:

您需要 2 + n 个项目:一个用于 exe(我们称之为 program.exe),一个用于合同(contracts.dll),一个用于每个 n 个插件(plugin.dll)。

program.exe 对contracts.dll 有硬引用,plugin.dll 也是如此。

使用强名称密钥对它们进行签名。请参阅http://msdn.microsoft.com/en-us/library/xc31ft41.aspx

在contracts.dll 中创建一个密封类LicenceQueryProvider,而不是接口ILicenceQueryProvider。确保它没有公共构造函数,只有一个内部构造函数,并且没有修改对象的方法(在构造时初始化,不可变且具有只读字段)。

使用 InternalsVisibleToAttribute 标记 contracts.dll,授予 program.exe 访问内部构造函数的权限。请参阅http://msdn.microsoft.com/en-us/library/System.Runtime.CompilerServices.InternalsVisibleToAttribute.aspx

这样,program.exe 可以调用这个对象的构造函数,plugin.dll 可以从中读取。

plugin.dll “知道”对象类由于强名称签名而未被修改。而且因为它是密封的,中间的人不能替代另一个实现。

现在记住我说过你可以让它更难破解,但这不是不可能的,而且永远不会,特别是如果你使用托管代码。

例如,中间的人可以使用反射来实例化具有内部构造函数的对象。

更糟糕的是,在您的插件中有从该对象读取的代码,并根据许可证信息做出决定。黑客可以将您的 plugin.dll 反编译为 IL,并将该代码替换为始终授予所有权限的代码。

混淆只会有一点帮助,但对反射攻击没有帮助。本机代码会使它变得更加困难,但本机代码也可以修补。

最终,代码在黑客的机器上,黑客可以为所欲为。他甚至可以在调试器下运行它,并修改内存中的数据。这是所有版权保护和许可机制都面临的问题。在我看来,许可证使您的客户更难使用您的软件,并且不会阻止坚定的黑客。您(或您的公司)是否想让您的客户难以使用您的软件?

现在这并不意味着没有解决方案。事实上有:黑客不能修改不在他机器上的代码。让代码在您控制的服务器上运行。客户端应用程序通过 Web 服务访问它。Web 服务对用户进行身份验证(不是调用代码,这是不可能的)。了解用户后,该服务可以验证用户的许可证。这是唯一的解决方案。

更新

需要明确一点:这样的服务需要运行对用户有价值的实际代码,而不仅仅是许可证检查。在后一种情况下,黑客可以修改客户端以简单地停止调用,甚至替换伪造的许可证服务器。但是,假设许可比重新创建服务中的实际逻辑更便宜。在这种情况下,即使是黑客也更愿意购买而不是重新创建代码。

于 2012-06-12T20:18:51.553 回答
1

没有万无一失的方法来保护您的软件。

我们曾经使用过(前面的广告)Safenet Inc 的 Sentinel 硬件密钥、dotfuscator pro 和智能组件来保护我们的一些应用程序。

硬件密钥可用于存储许可证(即每个功能/插件都有自己的许可证,可以在硬件密钥上启用并由应用程序查询)。可选地,他们的产品可用于加密您的应用程序 - 应用程序被加密,然后只能在内存中解密并在正确的硬件密钥连接到系统时启动。有一些反调试机制使某人更难使用调试器,等待应用程序在内存中解密然后复制它。

Dotfuscator 和智能程序集可用于“混淆”应用程序代码,从而使使用 Reflector 等工具进行反编译变得更加困难。

不过,这些工具都不是防弹的。但是“实现/窃取真的很痛苦”?我会这么说,但这是有代价的……你肯定可以在这些工具上投入很多钱。

于 2012-06-12T20:27:25.560 回答