.NET中的序列号(注册密钥)算法

6

关于IP安全等问题,已经有一些及时的帖子了,但我没有找到专门讨论算法的。在我目前的项目中,我们决定采用离线注册密钥系统。

我想我们最终的用户群大部分都是诚实的,所以我认为我们不需要太担心。另一方面,我宁愿不让随意破解者轻松获得访问权限。

那么,有哪些选项可以生成(和验证)密钥?硬件键入最有可能被排除,因为安装模型是从Samba共享运行在Intranet服务器上。此外,密钥应该有多长?

其次,验证算法被反射出来的危险有多大,即使它被混淆了?写非托管代码是否更好?

5个回答

10

我认为你将面临的主要问题并不在于你的注册算法及其难度(或缺乏难度)。

相反,问题出在这里:在你的代码中的某个点上,它仅涉及到简单的二进制决策 - 运行还是退出。攻击你的系统只需要找到并调整此决策点。

其他所有内容 - 代码混淆、强签名、篡改检测 - 都是为了使这一点更加困难,但不能够使其变得非常困难。


好的观点,我想它更多地是针对让诚实的人保持诚实 - 让购买比吸毒“更容易”。 也许这就是为什么有些人尝试在密钥中包含一些功能。不确定如何实现,除非你把密钥做得非常长,但这会使你面临数据执行攻击的风险,对吧? - lc.

2
通常,您需要选择一些数据以包含在密钥中,例如所有者和到期时间,可能甚至包括应用程序需要正确工作的一些小代码片段(从而使没有密钥很难使其正常工作)。然后使用数字签名方案(如RSA)使用公司的私钥对密钥进行数字签名。将公钥与应用程序可执行文件一起分发。然后,当您加载密钥时,只需验证签名是否有效,然后使用密钥中包含的数据。1024位或2048位密钥应该足够使用。
当然,无论您的代码有多复杂,总有人能够破解它或规避它。因此,您必须问自己的问题是,您想让它有多困难(记住更困难的方案对于您来说编码和维护更加困难)?通常情况下,存在着收益递减点,这个点通常非常低。只要程序没有密钥就无法工作,并且密钥足够复杂,您无法使用十六进制编辑器伪造一个密钥(或更改到期日期等),那么您可能就没问题了。

1
好主意,你说的关于收益递减的观点也很有道理。当然,“没有钥匙就无法使用”这个定义是主观的,但像我一直发现的那样,这些钥匙更多地是为了让诚实的人保持诚实,并使购买比吸毒“更容易”。 - lc.

1

就重构密钥而言,如果从托管代码到非托管代码的调用点被删除,那么将其编写为非托管代码可能并没有什么帮助。如果您使用Dotfuscator专业版,则可以通过启用其“篡改检测”选项来进行混淆。基本上,它会标记您的程序集,如果有人修改了它,您的代码可以执行各种操作。当然,黑客可以删除这个选项,但这需要更多的时间和精力。


1
我只发现一种非常好的锁定代码的方法。几乎每种序列验证形式都很容易被普通二年级程序员破解。
我使用了 .NET 中的 License 对象来做到这一点。在我的自制许可证对象中,它会读取一个“许可证”文件以查找“家”的位置。该许可证是一个加密字符串,该字符串的私钥在许可证对象中。
然后,许可证对象使用一个秘密密码来调用“home”,该密码也经过加密。服务器解密密码并进行验证...以防欺诈调查,还会记录 IP 和用户名。如果服务器可以验证密码,它将回复一个加密的秘密响应,以防止被伪造。如果无法验证,则连接将断开。不发送响应,因此另一端的许可对象失败。
当集成的许可对象失败时,它将自动引发异常,强制应用程序在调用许可证时失败并退出。
我花了大约两个工作日来编写服务器和许可证对象,所以这需要一点时间,但不是火箭科学。
如果您需要一些示例源代码或更多信息,请告诉我。我很乐意提供给您。

就像其他所有事情一样,这也遭受了Bevan概述的同样问题。而且它通过让软件一直“拨打主页”来惩罚您的合法用户。 - Nick Johnson
1
非常正确。我并不是很喜欢拨打主页,但根据许可模型,它确实有其优势。然而,我特别寻找不需要互联网连接的解决方案。我不想将用户锁定在每次运行时都必须连接的状态。 - lc.

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接