我在哪里可以存储(和管理)应用程序许可证信息?

时间:2013-12-19 07:43:03

标签: c# .net

我正在开发一个Windows应用程序。这要求用户注册使用它... 现在,我将许可证信息存储为APpData中的文件。但删除该文件会重置试用版日期。所以,我现在计划将其保存在注册表中。 但是,大多数用户在Windows中没有管理权限(受限用户)来访问注册表。 我能做什么 ?我在哪里可以保存我的序列号和日期?

3 个答案:

答案 0 :(得分:63)

在我看来,您需要更改 来管理许可证。我写了一个项目(hosted on git)来演示这里描述的一些技术。

其中

如果他们删除了许可证数据文件,那么试用会重启吗?如果文件不存在则不启动应用程序,并在首次安装时使用安装操作创建它。

现在你面临第二个问题:如果他们卸载并重新安装应用程序怎么办?第二步是将此文件移动到应用程序数据文件夹(例如Environment.SpecialFolder.CommonApplicationData)。这只是更安全一点(因为卸载时应用程序数据不会被删除),但他们仍然可以手动查找和删除它。如果应用程序将由低权限用户安装,则您无法做很多事情(您无法在注册表中的某处隐藏许可证)。

现在它是你和破解者之间的游戏。他们永远都会获胜。你只会让合法用户的生活更加艰难,所以请阅读 cum grano salis 。您可以在哪里存储许可证数据:

  • 注册表即可。亲:容易做到。缺点:容易破解,对于低权限用户,它每次只对一个用户有效。如果注册表项名称中包含\0,则可以以某种方式隐藏。看看this好帖子。
  • 文件即可。亲:容易做,IMO比Registry更安全一点。缺点:容易破解(但你可以隐藏它,稍后再看)。
  • 应用程序本身(将数据附加到您的可执行文件,关于this post上的数据很少)。亲:难以察觉。缺点:防病毒可能会将此视为......病毒和应用程序更新也可能会删除许可证(当然,如果您不能正确处理这种情况),那么它会使您的代码和部署更加复杂。

如何在文件中隐藏许可?
如果您要使用文件(它并不重要),您可能会考虑让破解者生活(一点点)更难。现在我想到了两个解决方案:

  • Alternate Data Streams。文件附加到另一个文件,他们只需在Windows资源管理器中搜索就看不到它。当然有管理它们的工具,但至少他们必须明确地搜索它。

  • 将其隐藏在应用程序数据中(例如,位图,使用steganography)。他们只是不知道它的许可证数据,哪些更安全?问题是他们可以轻松地反编译您的C#程序以查看您的操作(请参阅关于代码混淆的段落)。

可能还有很多人(幻想在这里是我们的主人)但不要忘记......破解者会找到它(如果他们真的想要的话),所以你必须平衡你的努力。

如何

保持您的许可架构,您现在已经走上了死路。您必须采取的决定是,如果他们使用试验的风险超过允许的风险高于他们因无聊保护而停止使用您的申请的风险。

<强>验证
如果您可以假设他们有网络连接,那么您可以使用某些唯一ID 在线验证许可证(仅在他们第一次运行您的应用程序时)(即使它是关于Windows 8的,您可以看看this post here on SO)。服务器端验证可能非常棘手(如果你想以正确的方式进行),在this post中解释了一个以适当的方式管理它的程序流的示例。

数据混淆/加密
您的许可证文件/数据现在位于安全的地方。几乎没有破解者会找到它。现在你需要另一个步骤:混淆。如果您的许可证数据一旦找到您的文件就是纯文本,那么它很容易更改。您有一些选择(按安全性和复杂性增加排序):

  • 模糊您的文件。如果他们无法通过简单的文本编辑器(甚至是十六进制编辑器)了解文件中的内容,那么他​​们将需要更多的时间和精力来破解它。例如,您可以压缩它们:请参阅有关XML file obfuscation with compression的帖子。请注意,简单的base64编码也会混淆您的文本文件。
  • 使用对称算法加密它们。即使是非常简单的也能很好地工作,在这里你只是试图隐藏数据。有关示例,请参阅this post。我没有理由更喜欢这种方法更简单的混淆。
  • 使用非对称算法对其进行加密。 This kind of encryption是复杂性和安全性的重要一步,只有当服务器/外部实体提供许可证令牌时,它才会非常有用。在这种情况下,它会混淆使用其私钥签名的许可证。客户端应用程序将使用其公钥验证签名,即使破解者将找到此文件(并将您的代码反编译为读取公钥),他们仍然无法更改它,因为他们没有私钥。

请注意,数据混淆/加密可与上述隐写术结合使用(例如,隐藏图像中的加密许可证文件)。

代码混淆
如果您未使用非对称加密的许可证签名,则最后一步是对代码进行模糊处理。无论您做什么,他们都能够看到您的代码,检查您的算法并解决它。很难过,你正在部署说明手册!如果您愿意,可以使用混淆器进行模糊处理,但我强烈建议您将许可证检查移到不太明显的位置。

  • 将所有与许可证相关的代码放在单独的DLL中。签名(请注意,已签名的程序集可能会被反编译并重新编译以删除签名,甚至有工具可以自动执行此操作)。
  • 将其打包在可执行资源中(名称不明显),不要部署DLL。
  • 处理事件AppDomain.AssemblyResolve,当您在运行时需要DLL时,您将在内存中解压缩并返回其字节流。在this Jeffrey Richter's post中了解有关此技术的更多信息。

我喜欢这种方法,因为他们会看到有许可证检查但是......他们不会找到许可证代码。当然,任何好的破解者都可以在10分钟内解决这个问题,但你可以(稍微多一些)安全地使用随机

结论

总结一下,这是可能所做的一系列列表,以提供更强大的许可证检查(当然,您可以跳过一个或多个步骤,但这会降低安全性):< / p>

  • 将许可证检查代码拆分为两个程序集(一个用于执行检查和管理许可证,另一个用于为该引擎提供公共接口)。
  • 强烈标记所有装配体。
  • 许可证引擎程序集嵌入许可证接口程序集中(请参阅代码混淆部分)。
  • 创建将管理许可证的许可证服务器。小心使其安全,具有安全连接和安全身份验证(请参阅验证部分)。
  • 将许可证文件本地保存在安全位置(请参阅 Where 部分)并使用非对称加密算法进行加密(请参阅数据混淆部分)
  • 有时使用许可证服务器验证许可证(请参阅验证部分)。

附录:软件保护加密狗
关于硬件密钥的小附录(软件保护加密狗)。它们是保护软件的宝贵工具,但您必须更加谨慎地设计保护。您可以假设硬件本身非常安全,但缺点是它与计算机的连接以及与软件的通信。

想象一下,只需将您的许可证存储到密钥中,一个黑客可以使用外部USB(假设您的SPD是USB)与多台计算机共享相同的密钥。您还应该在密钥中存储一些硬件唯一ID,但在这种情况下,弱点是连接(硬件可以由软件驱动程序模拟)。这很容易破解和这种错误的安全感(&#34;我使用软件保护加密狗,我的软件是安全的&#34; )将使您的应用程序均匀更容易受到攻击(因为您有可能忘记其他基本保护措施以简化许可证管理)。

使用SPD进行设计不佳保护的成本与效益应该会让您考虑使用普通的USB笔式驱动器。对于SPD,它需要1美元而不是15/20美元(或更多),并且您对休闲破解者具有相同级别的保护。当然,它不会阻止严重的饼干,但是设计糟糕的SPD也不会阻止它。

true 保护(假设您未在启用DRM的设备上运行)是一个加密狗,它也可以执行您的代码。如果您可以移动一些基本算法(至少将重要的 - 和动态的 - 支持文件解密)到密钥中然后破解您的软件,他们将需要破解硬件。对于一个半体面的加密狗来说,这是一项非常非常艰巨的任务。更仔细地设计这个和更多的代码,你移动到密钥,你将更安全。

在任何情况下,您都应该怀疑营销活动:使用加密狗进行软件保护并不容易。 可以(更多)更安全,但它并不像供应商所说的那么容易。在我看来,即插即用保护成本与其好处相比过高(好处是它会使得破解者的生活更加艰难)。

答案 1 :(得分:1)

不幸的是,无论您将许可证信息存储在客户端的计算机上,都会被滥用(因为这是他们的计算机!)。

唯一安全的方法是让您的程序通过远程服务签入,显然这需要很多开销。

我自己的方法是,如果客户弄乱他们的许可证密钥,那么他们应该期待问题,而您没有义务提供帮助。我会确保你的密钥包含有关它正在运行的机器的信息(以防止简单地复制密钥),但另外保持它非常简单。

在自行研究许可时,我发现了一种我倾向于坚持的理念 - 你通过错综复杂的许可设置驱逐更多潜在客户,而不是通过盗版来驱逐。

我的建议是你反转你的逻辑 - 而不是允许删除许可证密钥以重新启动免费试用,为什么不强迫他们拥有许可证密钥来解锁整个应用程序?

答案 2 :(得分:0)

如果您要写信给 HKEY_CURRENT_USER ,则不需要管理权限。 另一方面,写入 HKEY_LOCAL_MACHINE 需要管理权。

请确保当您open写入密钥时,将其称为

RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\YourAppPath", true);

如果这对你不起作用,有一个技巧可以写到可执行文件本身的末尾,但这是另一回事。