用于锁定程序/进行试用的序列号?

时间:2012-05-03 12:56:51

标签: c# visual-studio-2010 drm license-key serial-number

我正在寻找有关创建一个允许我锁定程序并将其置于试用模式的系统的指导。 我想要指导的部分是创建/检查密钥的算法,你们有什么建议应该是什么样的? 我正在使用c#。

3 个答案:

答案 0 :(得分:0)

最好的方法是实现自己的套接字协议,这种协议实际上是硬编码的,因此黑客无法对其进行解码,您应该不断更改它。另外,要检查许可证,您应该只是联系您的套接字服务器,套接字服务器只需联系数据库并检查密钥是否有效。

我就是这样做的,而且可以轻松实现

答案 1 :(得分:0)

您忘记了dotPeekJustDecompile.NET Reflector等工具可以轻松地将您的应用程序拆分为源代码。您的保护可以轻松删除。在SO上有许多类似的线程来处理混淆,序列号等。这里有两个关于代码混淆的链接。

https://stackoverflow.com/questions/1988451/net-obfuscation

Alternative for Obfuscation in the .NET world

老实说,你会花很多时间进行保护,最终可能浪费时间。这是不幸的,但这是现实。

答案 2 :(得分:0)

重新发帖:Generating a serial number for product activation

基本上 - 一旦软件出现在别人的计算机上,他们就可以随心所欲地修改软件,你无法阻止它们,缺乏法律行动,证明了反汇编和执行法律处罚。

如果您真的想要保护功能,您可以保持在线安全功能,并通过Web服务调用它。这样他们就不得不付钱,使用你的Web服务。 但是,如果您想找到一种生成序列密钥的方法。以下是我写的一篇文章,描述了一种生成“困难”的方法。串行密钥,需要很长时间才能完成,但需要少量时间来验证。 使用这种算法,您可以在数据库中预生成序列密钥,然后将其发送给客户。 唯一的问题是再次 - 有人可以反汇编您的应用程序,只需删除代码的许可部分。 我想改为使用户必须拥有有效的串行密钥才能下载软件,并下载任何和所有更新。这将激励成为合法和合法的客户。 因此,您可以使用这些序列的示例如下: 您可以使用以下代码生成100个序列组合。 保存它们,然后将它们出售给客户。 给他们一个序列号,产品密钥(号码)。

然后,当涉及激活时,他们将其输入您的网站,然后网站向他们发送软件。

您的网站使用序列密钥,他们输入的产品密钥,并将其与软件的密码短语相结合。 (以下示例中的Alpha) 如果3个部分联合在一起产生适当强度/难度的SHA256哈希值,那么它将认为它是成功注册的。 此外,您可以检查用户数据库,以查看该序列是否与相关客户匹配。 如果您想要真正安全,可以创建一个启动器应用程序,下载产品的二进制文件,并在成功验证串行密钥后通过Assembly.Load加载它们。 无论如何 - 重新发布现在正在开始。

<强>转播:

使用串行密钥,您需要考虑一些事项。

我在狩猎过程中看到过指向使用简单的Guid.NewGuid()的链接;接近然后对字符串进行一些转换以生成自定义样式的串行密钥。这很容易做到,但是产品所有者有责任跟踪数据库中的序列密钥,并且在一天结束时有人可能通过使用Guid.NewGuid()随机找到有效的序列号。他们自己。如果地球上的每个人同时开始生成Guids,碰撞机会很可能发生。

有一种解决方案可以通过在Guid.NewGuid()之上使用更复杂的算法来减少碰撞事件;

为此,我倾向于使用:

  1. Guid.NewGuid(); (仅前16个字符,减去 - (连字符)
  2. 不断增加或变化的价值。 (Nonce)(一个int将起作用:i ++ etc)
  3. 您将在网络中保密并保密的秘密盐。
  4. 困难因素:从比特币中借用这一原则。
  5. 好吧,让我们想象一下,我从一个guid中取出前16位数字。 然后我将它与Nonce和秘密盐结合起来, 然后使用SHA256从值中导出哈希值。 然后,我可以使用“难度”因子来确定哈希值是以0的数量还是以我想要的其他字符开头。

    例如:如果哈希有6个0前缀,那么我会保存所有数据,因为我刚刚找到了一个相当安全的串行密钥。

    当我的意思是安全时,我的意思是我找到了一个Serial,当它与产品密钥(Nonce)结合使用然后与秘密Salt一起使用时,它会产生符合我的生产标准的Hash。

    下面是一些示例代码 - 非常粗糙,因为我很无聊。

    我们的想法是您的应用程序可以将产品密钥和序列发送到激活服务器。服务器知道秘密盐。然后返回true或false以确定生成的哈希是否满足安全性要求。 如果不是:Serial无效,或对提供的密钥无效。 如果它具有所需的0&#39; s:它是有效的序列。

        Guid theGuid;
        string Hash = "";
        int iAccess = 0;
        string PrivateSalt = "Alpha";
        string SourceString = "";
        string guidString;
        while (true)
        {
            theGuid = Guid.NewGuid();
            guidString = theGuid.ToString().Replace("-", "").Substring(0,16);
            SourceString = guidString + "|" + iAccess.ToString() + "|" + PrivateSalt;
            byte[] data = Encoding.Default.GetBytes(SourceString);
            Hash = Crypto.GenerateSHA256(data);
            if (Hash.StartsWith(GetDiff()))
            {
                break;
            }
    
            iAccess++;
        }
        Console.WriteLine(SourceString+" Gives hash "+Hash);
        string s1, s2, s3, s4;
        s1 = guidString.Substring(0, 4);
        s2 = guidString.Substring(4, 4);
        s3 = guidString.Substring(8, 4);
        s4 = guidString.Substring(12, 4);
        string serial = s1 + "-" + s2 + "-" + s3 + "-" + s4;
    
        Console.WriteLine(serial + " :" + SourceString + " Gives hash " + Hash);
    

    GetDiff()基本上只是一个字符串:&#34; 000000&#34 ;;

    此方法的示例输出如下所示:

    d9c9-f6f0-45be-427a :d9c9f6f045be427a|15135|Alpha Gives hash    000000f718f69c8389d496e01d1e992946fe1b8cf72bc4200a7a2b800b40aa0a
    fe49-70b9-08d8-40df :fe4970b908d840df|9096414|Alpha Gives hash  000000e29cfccfb54d1e7edc816feb084f1a2cd11a20c3132a965f9048fc9bf4
    7f58-0636-c853-4f0a :7f580636c8534f0a|12297217|Alpha Gives hash 0000007bb44f39a964bbe985885451c3dc0e037fcd12951261404e48819bf89b
    6f65-82d3-d95b-4882 :6f6582d3d95b4882|15064854|Alpha Gives hash 000000f1a3bed79e441108cfd26d8733d3fc10f5cd66d234ed35fe2b769663a3
    edee-b8b7-9f6f-40ab :edeeb8b79f6f40ab|17782415|Alpha Gives hash 000000b70b96e7b008a96a860efc572fe868154ae81e67b9397249a51f2db71c
    0948-4bb3-7de4-4054 :09484bb37de44054|21105690|Alpha Gives hash 000000ec7317eccd5fd9bb701759a2b0e77d37099347d9d665f4b492a69ca3ec
    bbf5-5119-bf4e-463c :bbf55119bf4e463c|21715642|Alpha Gives hash 000000a134c886d01606da83cd5e8f672fddb6aa061968e9f08202c781514b16
    80f6-c9c5-0ddf-436d :80f6c9c50ddf436d|26450310|Alpha Gives hash 00000092305b2956381c23dacba5b8ff9a37ab994148b37677732dc2a0650386
    0a4f-143b-b5f5-48ca :0a4f143bb5f548ca|33691865|Alpha Gives hash 00000054ecdae57c6ec686b6084faf68ae49a78f7c07bbe8e51357d76de63870
    

    您可以通过在前缀中添加更多0来增加难度。 这意味着查找序列组合需要更长时间,但也会使其更安全。

    显然,您会将这些数据组合存储在某处,因此在激活期间,您可以比较序列号和产品密钥(Nonce)。

    在我的例子中:我正在使用Serial Key(16位),Incrementing int和秘密盐的Alpha字样。

    这使得生成串行密钥变得缓慢且CPU密集,但是可以非常快速地验证它们。

    IsSerialValid("edee-b8b7-9f6f-40ab", 17782415);
    
    public bool IsSerialValid(string serialCode, int ProductCode)
            {
                string SourceString = serialCode.Replace("-", "") + "|" + ProductCode.ToString() + "|" + "Alpha";
                byte[] data = Encoding.Default.GetBytes(SourceString);
                string Hash = Crypto.GenerateSHA256(data);
                if (Hash.StartsWith(GetDiff()))
                {
                    return true;
                }
                return false;
            }
    

    秘密Salt可能是一个代码短语,映射到您可能正在开发的不同产品。这允许您在多个产品系列中重复使用产品密钥(Nonce)值。