在Windows注册表中隐藏密钥的最佳位置?

Ste*_*eve 14 delphi registry winapi

我的Delphi程序具有内置保护机制,用于检查Internet上禁止的许可证密钥,并在找到列入黑名单的密钥时向用户显示消息.

我想将列入黑名单的密钥存储在注册表中,因此如果用户尝试重新输入(并且他/她未连接到Internet),则不会接受.

在Windows注册表中隐藏模糊条目的最佳方法是什么?

谢谢!


编辑:你们在那里有一些很好的答案,但我觉得我需要扩展这个问题.

这不是主流软件,而是企业软件.客户预先支付一年并获得一年的许可证密钥以进行激活.许可证密钥包含计算机ID,不能在其他地方使用.

问题是有些客户往往不及时付款或根本不付款.由于我不想打扰短于一年的许可证密钥(太多的管理开销),我需要一种方法来禁用他们的许可证,直到他们支付.

因此,应用程序现在将在启动时连接到Internet并检查其密钥是否已列入黑名单.如果是,我需要禁用访问权限.如果他们重新安装或阻止Internet访问,我需要知道密钥是否已被列入黑名单.

因此,我认为最好将其隐藏在注册表中.我的用户并不擅长使用注册表工具来监控注册表,但如果我把它放在HKLM/Software/MyCompany/MyProgram下,他们中的一些人可能会找到它.所以我需要一个他们之后无法找到它的地方.(没有人会期待它!)

有任何想法吗?

Jak*_*aka 26

我不认为注册表是隐藏此类信息的好地方,因为任何人都可以下载并使用Process Monitor(http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx)工具并查看你的程序对注册表的作用.

再想一想.如果将软件中的用户留在注册表中以及用户硬盘上的其他"秘密"位置,您可能会使您的软件用户不满意.通过监视软件调用的系统功能的工具也可以轻松发现这样的位置.

作为替代方案,您可以在发布新版本时将禁用的密钥嵌入到应用程序中.这样,禁用的密钥将隐藏在应用程序中,这使得破解者更难绕过保护.

这样做的缺点是,用户可能会使用禁止访问密钥的禁用密钥运行旧版本,但如果您的软件是使用新功能和添加的错误修正进行积极开发的,那么没有人会想要运行旧版本.如果你非常偏执,你可以发布"更新",它只更新嵌入式禁止键列表.

但最终没有软件保护方案是完美的.如果你的软件很受欢迎,总会有一个盗版者会发现你的保护并制作一个补丁甚至一个密钥生成器.


Ole*_*leg 26

隐藏键或值的最简单方法是创建名称中包含"\ 0"的键/值.你可以对原生函数做这方面的事情NtCreateKey(参见http://msdn.microsoft.com/en-us/library/ff556468.aspx)NtSetValueKey(参见http://msdn.microsoft.com/en-us/library/ ff557688.aspx)UNICODE_STRING用作参数而不是LPCTSTR.例如,您可以在http://www.codeproject.com/kb/system/NtRegistry.aspx中阅读有关本机注册表API使用的更多信息 .您可以在这里找到Delphi代码http://www.delphi3000.com/articles/article_3539.asp.

更新:因为很多人都读过这个问题,我想在答案中添加一些词语.我希望将问题的一部分划分为"使用许可证密钥从主题中隐藏Windows注册表中的密钥的标题".因为我读了一些答案(写在我之前),这些答案几乎只涉及许可证密钥的一部分而且几乎没有从标题中回答问题,我给我写了答案.

有许可证密钥的主题我发现非常复杂.这取决于所选择的许可模式.重要的是如何生成,分发(安装)和验证密钥.密钥应该是硬件依赖还是不依赖?它可以是每台计算机一台,也可以是每台计算机一台.密钥生成,密钥安装或密钥验证可以是某些在线服务(也可以是来自互联网)或没有.我可以继续......不同方法有很多方面,优点和缺点.

所以我决定回答标题中的主要问题,这个问题很清楚,并且有一个单独的兴趣.在清除所有要求后,我将在单独的问题中讨论有关许可证密钥的所有其他问题.

更新2基于更新的问题:在您的情况下,在我看来,使用基于激活票证的加密签名的某些场景会更好.例如,架构可能如下所示:

  • 您在客户端计算机上安装的软件需要激活.在激活之前,它无法工作或以非常有限的形式工作(例如,仅启用软件激活所需的一些菜单).
  • 您编写了一个服务器组件,该组件将在激活期间由客户端使用,以根据从客户端收到的激活请求生成许可证密钥.
  • 如果客户支付软件费用,则在服务器上的数据库中包含有关客户端"机器ID"(以任何形式)的信息.
  • 从客户端软件启动激活过程后(从菜单的程序开始或以任何其他方式),它会收集有关计算机的一些信息,如计算机名称("机器ID"),某些序列号或某些有关硬件或操作系统的其他信息,如果没有新的激活,则无法更改.软件发送给您服务器的此信息(这是激活请求).
  • 服务器验证具有"机器ID"的客户端是否支付了软件并且尚未激活.然后,服务器根据客户端发送的信息计算哈希值(SHA1,MD5或其他),并使用服务器的私钥(或服务器证书)对响应进行签名.已签名的票证服务器将发送回客户端.此票证将扮演许可证密钥的角色.
  • 在签名之前,服务器可以向故障单添加任何其他信息.例如,它可以添加有关日期的信息,直到软件应该有效(例如,当前日期加一年).因此,将发送回客户端的票证可以包含输入激活信息的散列和任何其他信息,所有这些都是您想要的.重要的只是信息应该签名.通常,您可以将完整客户端的请求作为明文包含在服务器票证中,而不是包含散列,但散列的使用a)会减小票证大小,并且b)使票证更安全一些.
  • 每个客户端都有公钥,对应于服务器用于签署激活票证的私钥.客户端在激活期间在文件系统的注册表中的任何位置保存从服务器接收的票证.
  • 每次下次启动客户端软件时,软件都会从注册表(或文件系统)读取保存的激活票据.然后,软件收集用于生成激活票据的相同信息,计算散列并将其与保存的票证中的散列进行比较.它根据公钥(或关于服务器的证书)验证票证的签名.此外,软件可以验证票证中的任何其他附加策略信息,例如票证有效的时间.

所有编写的只是一个粗略的模式,但它非常简单,并且是可扩展的.您只需要研究如何使用一些简单的加密操作并在您的软件中实现.

作为一种选择,你可以没有在线服务器,但是在软件中(例如在菜单中)可以生成激活请求按照电子邮件发送它.然后您可以离线(!!!)根据服务器请求生成激活票证,并通过电子邮件将票证发送回客户端.可以通过双击或软件中的其他简单导入可能性导入的简单Reg文件(在激活对话框中剪切和粘贴)可以结束软件激活过程.