生成的产品激活序列号(Generating a serial number for product

2019-08-04 00:18发布

首先,这不是一个有关生成其他产品的序列号的问题。 我不是在寻找到“黑客”等系列产品。

下面是我的要求:

  • 我想生成一个标准的期待编号:AILU7-ABCDE-54321-1234-AFCK-17UDF
  • 我需要一些过程,用于验证序列号是否为“有效” -这部分不必是极其复杂的。 也就是说,如果所有的数字之和为大于X的值 - 我会处之泰然,但如果有解决方案,在那里,处理这种复杂性对我来说,我会很高兴的使用它。
  • 该验证序列号的过程不能是服务器端。 即,我不能让到外部Web服务器的请求,以验证序列号是否有效。
  • 我需要一些方法来从序列号中拉出来的元数据。 也就是说,以后我已经验证该序列号是否正确,我需要能够从中读出一些值:“用户数限制”,“有效期限”等......
  • 序列号的验证将通过ASP.NET MVC 3应用程序来完成。 序列号的代所没有的,虽然做的方式。

我不是在寻找灵丹妙药,将完成所有这些要求,但更多或更少一些链接到文件或现有库,这将有助于我上手。 我所见过的唯一库是XHEO DeployLX库; 这仅仅是完全太多我的需求。

能否请您给我提供的是可以点我在正确的方向的任何信息?

Answer 1:

你看看布兰登·斯塔格斯文章对此很此事 ?

在Delphi中,但理论认为,任何一种语言。



Answer 2:

图书馆的大量在那里,一会是http://skgl.codeplex.com/ & http://softwareprotector.codeplex.com/ ,并配备了NuGet包为好。



Answer 3:

随着串行键,你需要考虑一些事情。

我看到在我的狩猎指向使用简单Guid.NewGuid()联系; 方法,然后做弦上一些转换,以使自定义风格的串行关键。 这是很容易做到的,但把责任推你的产品负责人来跟踪序列键在一个数据库中,并在一天结束的时候有潜力的人随机发现,通过使用Guid.NewGuid工作连续(); 他们自己。 如果每个人都在这个星球上开始发生在同一时间的GUID,碰撞的机会变得非常容易。

有一个排序的解决方案,使碰撞事件通过使用Guid.NewGuid的顶部更复杂的算法()不太可能;

对于这一点,我倾向于使用:

  1. Guid.NewGuid(); (仅前16个字符,减去 - (连字符)
  2. 不断增加或改变值。 (随机数)(一个int将工作:i ++在等)
  3. 一个秘密的盐,你将让您的网络中的隐私和安全。
  4. 一个难度系数:从Bitcoin借用这个原则。

好吧,让我们来想象我是从一个GUID取前16位。 然后,我结合起来,与随机值和秘密盐,然后用SHA256从价值导出散列。 然后我可以使用难度系数,以确定是否散列与0的,我想要的量或其它字符开头。

例如:如果哈希有六个0的前缀,那么我保存所有的数据了,因为我刚刚发现了一个相当安全的串行关键。

当我的意思是安全的,我的意思是我已经找到了一个串口,当与一个产品密钥(随机值)合并,然后用秘密盐使用,导致符合我的生产条件的哈希值。

一些示例代码如下 - 做得很粗糙,因为我很无聊。

这个想法是你的应用程序可以发送产品密钥和序列激活服务器。 服务器知道的秘密盐。 然后,它返回true或false,以确定是否生成的哈希满足安全要求。 如果没有:串行无效,或者不是有效的提供的关键。 如果它确实具有所需的0:它是一个有效的序列。

    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()基本上是一个字符串: “000000”;

从该方法中输出例如是这样的:

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到前缀增加难度。 这意味着找到序列组合将需要更长的时间,但也使得它更安全。

很明显,你会什么地方存储这些数据的组合,从而激活过程中,你可以比较的序列代码,以及产品密钥(随机数)。

在我的例子:我使用的序列密钥(16位),递增int和用于秘密盐字阿尔法。

这使得产生串行键缓慢和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;
        }

秘密盐可能是一个代号短语映射到您可能会开发不同的产品。 这允许跨越多个产品线,你再使用产品密钥(随机数)值。



文章来源: Generating a serial number for product activation