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

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

在我看来,重点是你必须改变你管理许可的方式。 我写了一个项目( 托管在git上 )来演示这里描述的一些技术。

哪里

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

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

现在这是你和骇客之间的游戏。 他们永远都会赢。 你只会让合法用户的生活变得更加艰难,所以阅读暨grano salis 。 您可以在哪里存储许可证数据:

  • 登记处 。 亲:容易做到。 缺点:容易破解,低权限用户每次只对一个用户有效。 如果注册表项的名称中包含\0 ,则可以以某种方式隐藏注册表项(在每个用户的基础中)。 看看这个好post。
  • 档案 。 Pro:容易做,IMO比Registry更安全一点。 缺点:容易破解(但你可以隐藏它更多,见后面)。
  • 应用程序本身 (将数据附加到您的可执行文件,关于此post的文字很少)。 亲:更难检测。 缺点:防病毒可能会将此视为……病毒和应用程序更新也可能会删除许可证(当然,如果您没有正确处理这种情况),这样会使您的代码和部署更加复杂。

如何在文件中隐藏许可证?
如果你要使用一个文件(无论它位于何处),你可能会考虑让破解者生活(一点点)更难。 我现在想到两种解决方案:

  • 备用数据流 。 文件附加到另一个文件,只有在Windows资源管理器中搜索它们才能看到它。 当然有管理它们的工具,但至少他们必须明确地搜索它。

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

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

怎么样

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

validation
如果您可以假设他们有网络连接,那么您可以使用一些唯一ID在线validation许可证(仅在他们第一次运行您的应用程序时)(即使它是关于Windows 8的,您可以在此处查看此post )。 服务器端validation可能相当棘手(如果你想以正确的方式进行),在这篇文章中解释了一个以适当的方式管理它的程序流程的例子。

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

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

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

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

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

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

结论

总结一下,这是一个列表,列出了您可以采取哪些措施来提供更强大的许可证检查(当然,您可以跳过一个或多个步骤,但这会降低安全性):

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

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

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

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

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

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

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

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

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

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

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

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

当你打开写入密钥时,请确保这样调用它

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

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